DeflaterHuffman.cs 22 KB

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