DeflaterHuffman.cs 23 KB

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