DeflaterHuffman.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. // DeflaterHuffman.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. namespace ICSharpCode.SharpZipLib.Zip.Compression
  39. {
  40. /// <summary>
  41. /// This is the DeflaterHuffman class.
  42. ///
  43. /// This class is <i>not</i> thread safe. This is inherent in the API, due
  44. /// to the split of deflate and setInput.
  45. ///
  46. /// author of the original java version : Jochen Hoenicke
  47. /// </summary>
  48. public class DeflaterHuffman
  49. {
  50. private static int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);
  51. private static int LITERAL_NUM = 286;
  52. private static int DIST_NUM = 30;
  53. private static int BITLEN_NUM = 19;
  54. private static int REP_3_6 = 16;
  55. private static int REP_3_10 = 17;
  56. private static int REP_11_138 = 18;
  57. private static int EOF_SYMBOL = 256;
  58. private static int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
  59. private static byte[] bit4Reverse = {
  60. 0,
  61. 8,
  62. 4,
  63. 12,
  64. 2,
  65. 10,
  66. 6,
  67. 14,
  68. 1,
  69. 9,
  70. 5,
  71. 13,
  72. 3,
  73. 11,
  74. 7,
  75. 15
  76. };
  77. public class Tree
  78. {
  79. public short[] freqs;
  80. public byte[] length;
  81. public int minNumCodes, numCodes;
  82. short[] codes;
  83. int[] bl_counts;
  84. int maxLength;
  85. DeflaterHuffman dh;
  86. public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength)
  87. {
  88. this.dh = dh;
  89. this.minNumCodes = minCodes;
  90. this.maxLength = maxLength;
  91. freqs = new short[elems];
  92. bl_counts = new int[maxLength];
  93. }
  94. public void Reset()
  95. {
  96. for (int i = 0; i < freqs.Length; i++) {
  97. freqs[i] = 0;
  98. }
  99. codes = null;
  100. length = null;
  101. }
  102. public void WriteSymbol(int code)
  103. {
  104. // if (DeflaterConstants.DEBUGGING) {
  105. // freqs[code]--;
  106. // // Console.Write("writeSymbol("+freqs.length+","+code+"): ");
  107. // }
  108. dh.pending.WriteBits(codes[code] & 0xffff, length[code]);
  109. }
  110. public void CheckEmpty()
  111. {
  112. bool empty = true;
  113. for (int i = 0; i < freqs.Length; i++) {
  114. if (freqs[i] != 0) {
  115. //Console.WriteLine("freqs["+i+"] == "+freqs[i]);
  116. empty = false;
  117. }
  118. }
  119. if (!empty) {
  120. throw new Exception();
  121. }
  122. //Console.WriteLine("checkEmpty suceeded!");
  123. }
  124. public void SetStaticCodes(short[] stCodes, byte[] stLength)
  125. {
  126. codes = stCodes;
  127. length = stLength;
  128. }
  129. public void BuildCodes()
  130. {
  131. int numSymbols = freqs.Length;
  132. int[] nextCode = new int[maxLength];
  133. int code = 0;
  134. codes = new short[freqs.Length];
  135. // if (DeflaterConstants.DEBUGGING) {
  136. // //Console.WriteLine("buildCodes: "+freqs.Length);
  137. // }
  138. for (int bits = 0; bits < maxLength; bits++) {
  139. nextCode[bits] = code;
  140. code += bl_counts[bits] << (15 - bits);
  141. // if (DeflaterConstants.DEBUGGING) {
  142. // //Console.WriteLine("bits: "+(bits+1)+" count: "+bl_counts[bits]
  143. // +" nextCode: "+code); // HACK : Integer.toHexString(
  144. // }
  145. }
  146. if (DeflaterConstants.DEBUGGING && code != 65536) {
  147. throw new Exception("Inconsistent bl_counts!");
  148. }
  149. for (int i=0; i < numCodes; i++) {
  150. int bits = length[i];
  151. if (bits > 0) {
  152. // if (DeflaterConstants.DEBUGGING) {
  153. // //Console.WriteLine("codes["+i+"] = rev(" + nextCode[bits-1]+")," // HACK : Integer.toHexString(
  154. // +bits);
  155. // }
  156. codes[i] = BitReverse(nextCode[bits-1]);
  157. nextCode[bits-1] += 1 << (16 - bits);
  158. }
  159. }
  160. }
  161. void BuildLength(int[] childs)
  162. {
  163. this.length = new byte [freqs.Length];
  164. int numNodes = childs.Length / 2;
  165. int numLeafs = (numNodes + 1) / 2;
  166. int overflow = 0;
  167. for (int i = 0; i < maxLength; i++) {
  168. bl_counts[i] = 0;
  169. }
  170. /* First calculate optimal bit lengths */
  171. int[] lengths = new int[numNodes];
  172. lengths[numNodes-1] = 0;
  173. for (int i = numNodes - 1; i >= 0; i--) {
  174. if (childs[2*i+1] != -1) {
  175. int bitLength = lengths[i] + 1;
  176. if (bitLength > maxLength) {
  177. bitLength = maxLength;
  178. overflow++;
  179. }
  180. lengths[childs[2*i]] = lengths[childs[2*i+1]] = bitLength;
  181. } else {
  182. /* A leaf node */
  183. int bitLength = lengths[i];
  184. bl_counts[bitLength - 1]++;
  185. this.length[childs[2*i]] = (byte) lengths[i];
  186. }
  187. }
  188. // if (DeflaterConstants.DEBUGGING) {
  189. // //Console.WriteLine("Tree "+freqs.Length+" lengths:");
  190. // for (int i=0; i < numLeafs; i++) {
  191. // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
  192. // + " len: "+length[childs[2*i]]);
  193. // }
  194. // }
  195. if (overflow == 0) {
  196. return;
  197. }
  198. int incrBitLen = maxLength - 1;
  199. do {
  200. /* Find the first bit length which could increase: */
  201. while (bl_counts[--incrBitLen] == 0)
  202. ;
  203. /* Move this node one down and remove a corresponding
  204. * amount of overflow nodes.
  205. */
  206. do {
  207. bl_counts[incrBitLen]--;
  208. bl_counts[++incrBitLen]++;
  209. overflow -= 1 << (maxLength - 1 - incrBitLen);
  210. } while (overflow > 0 && incrBitLen < maxLength - 1);
  211. } while (overflow > 0);
  212. /* We may have overshot above. Move some nodes from maxLength to
  213. * maxLength-1 in that case.
  214. */
  215. bl_counts[maxLength-1] += overflow;
  216. bl_counts[maxLength-2] -= overflow;
  217. /* Now recompute all bit lengths, scanning in increasing
  218. * frequency. It is simpler to reconstruct all lengths instead of
  219. * fixing only the wrong ones. This idea is taken from 'ar'
  220. * written by Haruhiko Okumura.
  221. *
  222. * The nodes were inserted with decreasing frequency into the childs
  223. * array.
  224. */
  225. int nodePtr = 2 * numLeafs;
  226. for (int bits = maxLength; bits != 0; bits--) {
  227. int n = bl_counts[bits-1];
  228. while (n > 0) {
  229. int childPtr = 2*childs[nodePtr++];
  230. if (childs[childPtr + 1] == -1) {
  231. /* We found another leaf */
  232. length[childs[childPtr]] = (byte) bits;
  233. n--;
  234. }
  235. }
  236. }
  237. // if (DeflaterConstants.DEBUGGING) {
  238. // //Console.WriteLine("*** After overflow elimination. ***");
  239. // for (int i=0; i < numLeafs; i++) {
  240. // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
  241. // + " len: "+length[childs[2*i]]);
  242. // }
  243. // }
  244. }
  245. public void BuildTree()
  246. {
  247. int numSymbols = freqs.Length;
  248. /* heap is a priority queue, sorted by frequency, least frequent
  249. * nodes first. The heap is a binary tree, with the property, that
  250. * the parent node is smaller than both child nodes. This assures
  251. * that the smallest node is the first parent.
  252. *
  253. * The binary tree is encoded in an array: 0 is root node and
  254. * the nodes 2*n+1, 2*n+2 are the child nodes of node n.
  255. */
  256. int[] heap = new int[numSymbols];
  257. int heapLen = 0;
  258. int maxCode = 0;
  259. for (int n = 0; n < numSymbols; n++) {
  260. int freq = freqs[n];
  261. if (freq != 0) {
  262. /* Insert n into heap */
  263. int pos = heapLen++;
  264. int ppos;
  265. while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq) {
  266. heap[pos] = heap[ppos];
  267. pos = ppos;
  268. }
  269. heap[pos] = n;
  270. maxCode = n;
  271. }
  272. }
  273. /* We could encode a single literal with 0 bits but then we
  274. * don't see the literals. Therefore we force at least two
  275. * literals to avoid this case. We don't care about order in
  276. * this case, both literals get a 1 bit code.
  277. */
  278. while (heapLen < 2) {
  279. int node = maxCode < 2 ? ++maxCode : 0;
  280. heap[heapLen++] = node;
  281. }
  282. numCodes = Math.Max(maxCode + 1, minNumCodes);
  283. int numLeafs = heapLen;
  284. int[] childs = new int[4*heapLen - 2];
  285. int[] values = new int[2*heapLen - 1];
  286. int numNodes = numLeafs;
  287. for (int i = 0; i < heapLen; i++) {
  288. int node = heap[i];
  289. childs[2*i] = node;
  290. childs[2*i+1] = -1;
  291. values[i] = freqs[node] << 8;
  292. heap[i] = i;
  293. }
  294. /* Construct the Huffman tree by repeatedly combining the least two
  295. * frequent nodes.
  296. */
  297. do {
  298. int first = heap[0];
  299. int last = heap[--heapLen];
  300. /* Propagate the hole to the leafs of the heap */
  301. int ppos = 0;
  302. int path = 1;
  303. while (path < heapLen) {
  304. if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {
  305. path++;
  306. }
  307. heap[ppos] = heap[path];
  308. ppos = path;
  309. path = path * 2 + 1;
  310. }
  311. /* Now propagate the last element down along path. Normally
  312. * it shouldn't go too deep.
  313. */
  314. int lastVal = values[last];
  315. while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {
  316. heap[path] = heap[ppos];
  317. }
  318. heap[path] = last;
  319. int second = heap[0];
  320. /* Create a new node father of first and second */
  321. last = numNodes++;
  322. childs[2*last] = first;
  323. childs[2*last+1] = second;
  324. int mindepth = Math.Min(values[first] & 0xff, values[second] & 0xff);
  325. values[last] = lastVal = values[first] + values[second] - mindepth + 1;
  326. /* Again, propagate the hole to the leafs */
  327. ppos = 0;
  328. path = 1;
  329. while (path < heapLen) {
  330. if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {
  331. path++;
  332. }
  333. heap[ppos] = heap[path];
  334. ppos = path;
  335. path = ppos * 2 + 1;
  336. }
  337. /* Now propagate the new element down along path */
  338. while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {
  339. heap[path] = heap[ppos];
  340. }
  341. heap[path] = last;
  342. } while (heapLen > 1);
  343. if (heap[0] != childs.Length / 2 - 1) {
  344. throw new Exception("Weird!");
  345. }
  346. BuildLength(childs);
  347. }
  348. public int GetEncodedLength()
  349. {
  350. int len = 0;
  351. for (int i = 0; i < freqs.Length; i++) {
  352. len += freqs[i] * length[i];
  353. }
  354. return len;
  355. }
  356. public void CalcBLFreq(Tree blTree)
  357. {
  358. int max_count; /* max repeat count */
  359. int min_count; /* min repeat count */
  360. int count; /* repeat count of the current code */
  361. int curlen = -1; /* length of current code */
  362. int i = 0;
  363. while (i < numCodes) {
  364. count = 1;
  365. int nextlen = length[i];
  366. if (nextlen == 0) {
  367. max_count = 138;
  368. min_count = 3;
  369. } else {
  370. max_count = 6;
  371. min_count = 3;
  372. if (curlen != nextlen) {
  373. blTree.freqs[nextlen]++;
  374. count = 0;
  375. }
  376. }
  377. curlen = nextlen;
  378. i++;
  379. while (i < numCodes && curlen == length[i]) {
  380. i++;
  381. if (++count >= max_count) {
  382. break;
  383. }
  384. }
  385. if (count < min_count) {
  386. blTree.freqs[curlen] += (short)count;
  387. } else if (curlen != 0) {
  388. blTree.freqs[REP_3_6]++;
  389. } else if (count <= 10) {
  390. blTree.freqs[REP_3_10]++;
  391. } else {
  392. blTree.freqs[REP_11_138]++;
  393. }
  394. }
  395. }
  396. public void WriteTree(Tree blTree)
  397. {
  398. int max_count; /* max repeat count */
  399. int min_count; /* min repeat count */
  400. int count; /* repeat count of the current code */
  401. int curlen = -1; /* length of current code */
  402. int i = 0;
  403. while (i < numCodes) {
  404. count = 1;
  405. int nextlen = length[i];
  406. if (nextlen == 0) {
  407. max_count = 138;
  408. min_count = 3;
  409. } else {
  410. max_count = 6;
  411. min_count = 3;
  412. if (curlen != nextlen) {
  413. blTree.WriteSymbol(nextlen);
  414. count = 0;
  415. }
  416. }
  417. curlen = nextlen;
  418. i++;
  419. while (i < numCodes && curlen == length[i]) {
  420. i++;
  421. if (++count >= max_count) {
  422. break;
  423. }
  424. }
  425. if (count < min_count) {
  426. while (count-- > 0) {
  427. blTree.WriteSymbol(curlen);
  428. }
  429. } else if (curlen != 0) {
  430. blTree.WriteSymbol(REP_3_6);
  431. dh.pending.WriteBits(count - 3, 2);
  432. } else if (count <= 10) {
  433. blTree.WriteSymbol(REP_3_10);
  434. dh.pending.WriteBits(count - 3, 3);
  435. } else {
  436. blTree.WriteSymbol(REP_11_138);
  437. dh.pending.WriteBits(count - 11, 7);
  438. }
  439. }
  440. }
  441. }
  442. public DeflaterPending pending;
  443. private Tree literalTree, distTree, blTree;
  444. private short[] d_buf;
  445. private byte[] l_buf;
  446. private int last_lit;
  447. private int extra_bits;
  448. private static short[] staticLCodes;
  449. private static byte[] staticLLength;
  450. private static short[] staticDCodes;
  451. private static byte[] staticDLength;
  452. /// <summary>
  453. /// Reverse the bits of a 16 bit value.
  454. /// </summary>
  455. public static short BitReverse(int value)
  456. {
  457. return (short) (bit4Reverse[value & 0xF] << 12 |
  458. bit4Reverse[(value >> 4) & 0xF] << 8 |
  459. bit4Reverse[(value >> 8) & 0xF] << 4 |
  460. bit4Reverse[value >> 12]);
  461. }
  462. static DeflaterHuffman()
  463. {
  464. /* See RFC 1951 3.2.6 */
  465. /* Literal codes */
  466. staticLCodes = new short[LITERAL_NUM];
  467. staticLLength = new byte[LITERAL_NUM];
  468. int i = 0;
  469. while (i < 144) {
  470. staticLCodes[i] = BitReverse((0x030 + i) << 8);
  471. staticLLength[i++] = 8;
  472. }
  473. while (i < 256) {
  474. staticLCodes[i] = BitReverse((0x190 - 144 + i) << 7);
  475. staticLLength[i++] = 9;
  476. }
  477. while (i < 280) {
  478. staticLCodes[i] = BitReverse((0x000 - 256 + i) << 9);
  479. staticLLength[i++] = 7;
  480. }
  481. while (i < LITERAL_NUM) {
  482. staticLCodes[i] = BitReverse((0x0c0 - 280 + i) << 8);
  483. staticLLength[i++] = 8;
  484. }
  485. /* Distant codes */
  486. staticDCodes = new short[DIST_NUM];
  487. staticDLength = new byte[DIST_NUM];
  488. for (i = 0; i < DIST_NUM; i++) {
  489. staticDCodes[i] = BitReverse(i << 11);
  490. staticDLength[i] = 5;
  491. }
  492. }
  493. public DeflaterHuffman(DeflaterPending pending)
  494. {
  495. this.pending = pending;
  496. literalTree = new Tree(this, LITERAL_NUM, 257, 15);
  497. distTree = new Tree(this, DIST_NUM, 1, 15);
  498. blTree = new Tree(this, BITLEN_NUM, 4, 7);
  499. d_buf = new short[BUFSIZE];
  500. l_buf = new byte [BUFSIZE];
  501. }
  502. public void Reset()
  503. {
  504. last_lit = 0;
  505. extra_bits = 0;
  506. literalTree.Reset();
  507. distTree.Reset();
  508. blTree.Reset();
  509. }
  510. int Lcode(int len)
  511. {
  512. if (len == 255) {
  513. return 285;
  514. }
  515. int code = 257;
  516. while (len >= 8) {
  517. code += 4;
  518. len >>= 1;
  519. }
  520. return code + len;
  521. }
  522. int Dcode(int distance)
  523. {
  524. int code = 0;
  525. while (distance >= 4) {
  526. code += 2;
  527. distance >>= 1;
  528. }
  529. return code + distance;
  530. }
  531. public void SendAllTrees(int blTreeCodes)
  532. {
  533. blTree.BuildCodes();
  534. literalTree.BuildCodes();
  535. distTree.BuildCodes();
  536. pending.WriteBits(literalTree.numCodes - 257, 5);
  537. pending.WriteBits(distTree.numCodes - 1, 5);
  538. pending.WriteBits(blTreeCodes - 4, 4);
  539. for (int rank = 0; rank < blTreeCodes; rank++) {
  540. pending.WriteBits(blTree.length[BL_ORDER[rank]], 3);
  541. }
  542. literalTree.WriteTree(blTree);
  543. distTree.WriteTree(blTree);
  544. // if (DeflaterConstants.DEBUGGING) {
  545. // blTree.CheckEmpty();
  546. // }
  547. }
  548. public void CompressBlock()
  549. {
  550. for (int i = 0; i < last_lit; i++) {
  551. int litlen = l_buf[i] & 0xff;
  552. int dist = d_buf[i];
  553. if (dist-- != 0) {
  554. // if (DeflaterConstants.DEBUGGING) {
  555. // Console.Write("["+(dist+1)+","+(litlen+3)+"]: ");
  556. // }
  557. int lc = Lcode(litlen);
  558. literalTree.WriteSymbol(lc);
  559. int bits = (lc - 261) / 4;
  560. if (bits > 0 && bits <= 5) {
  561. pending.WriteBits(litlen & ((1 << bits) - 1), bits);
  562. }
  563. int dc = Dcode(dist);
  564. distTree.WriteSymbol(dc);
  565. bits = dc / 2 - 1;
  566. if (bits > 0) {
  567. pending.WriteBits(dist & ((1 << bits) - 1), bits);
  568. }
  569. } else {
  570. // if (DeflaterConstants.DEBUGGING) {
  571. // if (litlen > 32 && litlen < 127) {
  572. // Console.Write("("+(char)litlen+"): ");
  573. // } else {
  574. // Console.Write("{"+litlen+"}: ");
  575. // }
  576. // }
  577. literalTree.WriteSymbol(litlen);
  578. }
  579. }
  580. // if (DeflaterConstants.DEBUGGING) {
  581. // Console.Write("EOF: ");
  582. // }
  583. literalTree.WriteSymbol(EOF_SYMBOL);
  584. // if (DeflaterConstants.DEBUGGING) {
  585. // literalTree.CheckEmpty();
  586. // distTree.CheckEmpty();
  587. // }
  588. }
  589. public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
  590. {
  591. // if (DeflaterConstants.DEBUGGING) {
  592. // //Console.WriteLine("Flushing stored block "+ storedLength);
  593. // }
  594. pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);
  595. pending.AlignToByte();
  596. pending.WriteShort(storedLength);
  597. pending.WriteShort(~storedLength);
  598. pending.WriteBlock(stored, storedOffset, storedLength);
  599. Reset();
  600. }
  601. public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
  602. {
  603. literalTree.freqs[EOF_SYMBOL]++;
  604. /* Build trees */
  605. literalTree.BuildTree();
  606. distTree.BuildTree();
  607. /* Calculate bitlen frequency */
  608. literalTree.CalcBLFreq(blTree);
  609. distTree.CalcBLFreq(blTree);
  610. /* Build bitlen tree */
  611. blTree.BuildTree();
  612. int blTreeCodes = 4;
  613. for (int i = 18; i > blTreeCodes; i--) {
  614. if (blTree.length[BL_ORDER[i]] > 0) {
  615. blTreeCodes = i+1;
  616. }
  617. }
  618. int opt_len = 14 + blTreeCodes * 3 + blTree.GetEncodedLength() +
  619. literalTree.GetEncodedLength() + distTree.GetEncodedLength() +
  620. extra_bits;
  621. int static_len = extra_bits;
  622. for (int i = 0; i < LITERAL_NUM; i++) {
  623. static_len += literalTree.freqs[i] * staticLLength[i];
  624. }
  625. for (int i = 0; i < DIST_NUM; i++) {
  626. static_len += distTree.freqs[i] * staticDLength[i];
  627. }
  628. if (opt_len >= static_len) {
  629. /* Force static trees */
  630. opt_len = static_len;
  631. }
  632. if ((storedOffset >= 0) && (storedLength + 4 < (opt_len >> 3))) {
  633. /* Store Block */
  634. // if (DeflaterConstants.DEBUGGING) {
  635. // //Console.WriteLine("Storing, since " + storedLength + " < " + opt_len
  636. // + " <= " + static_len);
  637. // }
  638. FlushStoredBlock(stored, storedOffset, storedLength, lastBlock);
  639. } else if (opt_len == static_len) {
  640. /* Encode with static tree */
  641. pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3);
  642. literalTree.SetStaticCodes(staticLCodes, staticLLength);
  643. distTree.SetStaticCodes(staticDCodes, staticDLength);
  644. CompressBlock();
  645. Reset();
  646. } else {
  647. /* Encode with dynamic tree */
  648. pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3);
  649. SendAllTrees(blTreeCodes);
  650. CompressBlock();
  651. Reset();
  652. }
  653. }
  654. public bool IsFull()
  655. {
  656. // return last_lit + 16 >= BUFSIZE; // HACK: This was == 'last_lit == BUFSIZE', but errors occured with DeflateFast
  657. return last_lit >= BUFSIZE; // -jr- This is the correct form!
  658. }
  659. public bool TallyLit(int lit)
  660. {
  661. // if (DeflaterConstants.DEBUGGING) {
  662. // if (lit > 32 && lit < 127) {
  663. // //Console.WriteLine("("+(char)lit+")");
  664. // } else {
  665. // //Console.WriteLine("{"+lit+"}");
  666. // }
  667. // }
  668. d_buf[last_lit] = 0;
  669. l_buf[last_lit++] = (byte)lit;
  670. literalTree.freqs[lit]++;
  671. return IsFull();
  672. }
  673. public bool TallyDist(int dist, int len)
  674. {
  675. // if (DeflaterConstants.DEBUGGING) {
  676. // //Console.WriteLine("["+dist+","+len+"]");
  677. // }
  678. d_buf[last_lit] = (short)dist;
  679. l_buf[last_lit++] = (byte)(len - 3);
  680. int lc = Lcode(len - 3);
  681. literalTree.freqs[lc]++;
  682. if (lc >= 265 && lc < 285) {
  683. extra_bits += (lc - 261) / 4;
  684. }
  685. int dc = Dcode(dist - 1);
  686. distTree.freqs[dc]++;
  687. if (dc >= 4) {
  688. extra_bits += dc / 2 - 1;
  689. }
  690. return IsFull();
  691. }
  692. }
  693. }