BZip2OutputStream.cs 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033
  1. using ICSharpCode.SharpZipLib.Checksum;
  2. using System;
  3. using System.IO;
  4. namespace ICSharpCode.SharpZipLib.BZip2
  5. {
  6. /// <summary>
  7. /// An output stream that compresses into the BZip2 format
  8. /// including file header chars into another stream.
  9. /// </summary>
  10. public class BZip2OutputStream : Stream
  11. {
  12. #region Constants
  13. private const int SETMASK = (1 << 21);
  14. private const int CLEARMASK = (~SETMASK);
  15. private const int GREATER_ICOST = 15;
  16. private const int LESSER_ICOST = 0;
  17. private const int SMALL_THRESH = 20;
  18. private const int DEPTH_THRESH = 10;
  19. /*--
  20. If you are ever unlucky/improbable enough
  21. to get a stack overflow whilst sorting,
  22. increase the following constant and try
  23. again. In practice I have never seen the
  24. stack go above 27 elems, so the following
  25. limit seems very generous.
  26. --*/
  27. private const int QSORT_STACK_SIZE = 1000;
  28. /*--
  29. Knuth's increments seem to work better
  30. than Incerpi-Sedgewick here. Possibly
  31. because the number of elems to sort is
  32. usually small, typically <= 20.
  33. --*/
  34. private readonly int[] increments = {
  35. 1, 4, 13, 40, 121, 364, 1093, 3280,
  36. 9841, 29524, 88573, 265720,
  37. 797161, 2391484
  38. };
  39. #endregion Constants
  40. #region Instance Fields
  41. /*--
  42. index of the last char in the block, so
  43. the block size == last + 1.
  44. --*/
  45. private int last;
  46. /*--
  47. index in zptr[] of original string after sorting.
  48. --*/
  49. private int origPtr;
  50. /*--
  51. always: in the range 0 .. 9.
  52. The current block size is 100000 * this number.
  53. --*/
  54. private int blockSize100k;
  55. private bool blockRandomised;
  56. private int bytesOut;
  57. private int bsBuff;
  58. private int bsLive;
  59. private IChecksum mCrc = new BZip2Crc();
  60. private bool[] inUse = new bool[256];
  61. private int nInUse;
  62. private char[] seqToUnseq = new char[256];
  63. private char[] unseqToSeq = new char[256];
  64. private char[] selector = new char[BZip2Constants.MaximumSelectors];
  65. private char[] selectorMtf = new char[BZip2Constants.MaximumSelectors];
  66. private byte[] block;
  67. private int[] quadrant;
  68. private int[] zptr;
  69. private short[] szptr;
  70. private int[] ftab;
  71. private int nMTF;
  72. private int[] mtfFreq = new int[BZip2Constants.MaximumAlphaSize];
  73. /*
  74. * Used when sorting. If too many long comparisons
  75. * happen, we stop sorting, randomise the block
  76. * slightly, and try again.
  77. */
  78. private int workFactor;
  79. private int workDone;
  80. private int workLimit;
  81. private bool firstAttempt;
  82. private int nBlocksRandomised;
  83. private int currentChar = -1;
  84. private int runLength;
  85. private uint blockCRC, combinedCRC;
  86. private int allowableBlockSize;
  87. private readonly Stream baseStream;
  88. private bool disposed_;
  89. #endregion Instance Fields
  90. /// <summary>
  91. /// Construct a default output stream with maximum block size
  92. /// </summary>
  93. /// <param name="stream">The stream to write BZip data onto.</param>
  94. public BZip2OutputStream(Stream stream) : this(stream, 9)
  95. {
  96. }
  97. /// <summary>
  98. /// Initialise a new instance of the <see cref="BZip2OutputStream"></see>
  99. /// for the specified stream, using the given blocksize.
  100. /// </summary>
  101. /// <param name="stream">The stream to write compressed data to.</param>
  102. /// <param name="blockSize">The block size to use.</param>
  103. /// <remarks>
  104. /// Valid block sizes are in the range 1..9, with 1 giving
  105. /// the lowest compression and 9 the highest.
  106. /// </remarks>
  107. public BZip2OutputStream(Stream stream, int blockSize)
  108. {
  109. if (stream == null)
  110. throw new ArgumentNullException(nameof(stream));
  111. baseStream = stream;
  112. bsLive = 0;
  113. bsBuff = 0;
  114. bytesOut = 0;
  115. workFactor = 50;
  116. if (blockSize > 9)
  117. {
  118. blockSize = 9;
  119. }
  120. if (blockSize < 1)
  121. {
  122. blockSize = 1;
  123. }
  124. blockSize100k = blockSize;
  125. AllocateCompressStructures();
  126. Initialize();
  127. InitBlock();
  128. }
  129. /// <summary>
  130. /// Ensures that resources are freed and other cleanup operations
  131. /// are performed when the garbage collector reclaims the BZip2OutputStream.
  132. /// </summary>
  133. ~BZip2OutputStream()
  134. {
  135. Dispose(false);
  136. }
  137. /// <summary>
  138. /// Gets or sets a flag indicating ownership of underlying stream.
  139. /// When the flag is true <see cref="Stream.Dispose()" /> will close the underlying stream also.
  140. /// </summary>
  141. /// <remarks>The default value is true.</remarks>
  142. public bool IsStreamOwner { get; set; } = true;
  143. /// <summary>
  144. /// Gets a value indicating whether the current stream supports reading
  145. /// </summary>
  146. public override bool CanRead
  147. {
  148. get
  149. {
  150. return false;
  151. }
  152. }
  153. /// <summary>
  154. /// Gets a value indicating whether the current stream supports seeking
  155. /// </summary>
  156. public override bool CanSeek
  157. {
  158. get
  159. {
  160. return false;
  161. }
  162. }
  163. /// <summary>
  164. /// Gets a value indicating whether the current stream supports writing
  165. /// </summary>
  166. public override bool CanWrite
  167. {
  168. get
  169. {
  170. return baseStream.CanWrite;
  171. }
  172. }
  173. /// <summary>
  174. /// Gets the length in bytes of the stream
  175. /// </summary>
  176. public override long Length
  177. {
  178. get
  179. {
  180. return baseStream.Length;
  181. }
  182. }
  183. /// <summary>
  184. /// Gets or sets the current position of this stream.
  185. /// </summary>
  186. public override long Position
  187. {
  188. get
  189. {
  190. return baseStream.Position;
  191. }
  192. set
  193. {
  194. throw new NotSupportedException("BZip2OutputStream position cannot be set");
  195. }
  196. }
  197. /// <summary>
  198. /// Sets the current position of this stream to the given value.
  199. /// </summary>
  200. /// <param name="offset">The point relative to the offset from which to being seeking.</param>
  201. /// <param name="origin">The reference point from which to begin seeking.</param>
  202. /// <returns>The new position in the stream.</returns>
  203. public override long Seek(long offset, SeekOrigin origin)
  204. {
  205. throw new NotSupportedException("BZip2OutputStream Seek not supported");
  206. }
  207. /// <summary>
  208. /// Sets the length of this stream to the given value.
  209. /// </summary>
  210. /// <param name="value">The new stream length.</param>
  211. public override void SetLength(long value)
  212. {
  213. throw new NotSupportedException("BZip2OutputStream SetLength not supported");
  214. }
  215. /// <summary>
  216. /// Read a byte from the stream advancing the position.
  217. /// </summary>
  218. /// <returns>The byte read cast to an int; -1 if end of stream.</returns>
  219. public override int ReadByte()
  220. {
  221. throw new NotSupportedException("BZip2OutputStream ReadByte not supported");
  222. }
  223. /// <summary>
  224. /// Read a block of bytes
  225. /// </summary>
  226. /// <param name="buffer">The buffer to read into.</param>
  227. /// <param name="offset">The offset in the buffer to start storing data at.</param>
  228. /// <param name="count">The maximum number of bytes to read.</param>
  229. /// <returns>The total number of bytes read. This might be less than the number of bytes
  230. /// requested if that number of bytes are not currently available, or zero
  231. /// if the end of the stream is reached.</returns>
  232. public override int Read(byte[] buffer, int offset, int count)
  233. {
  234. throw new NotSupportedException("BZip2OutputStream Read not supported");
  235. }
  236. /// <summary>
  237. /// Write a block of bytes to the stream
  238. /// </summary>
  239. /// <param name="buffer">The buffer containing data to write.</param>
  240. /// <param name="offset">The offset of the first byte to write.</param>
  241. /// <param name="count">The number of bytes to write.</param>
  242. public override void Write(byte[] buffer, int offset, int count)
  243. {
  244. if (buffer == null)
  245. {
  246. throw new ArgumentNullException(nameof(buffer));
  247. }
  248. if (offset < 0)
  249. {
  250. throw new ArgumentOutOfRangeException(nameof(offset));
  251. }
  252. if (count < 0)
  253. {
  254. throw new ArgumentOutOfRangeException(nameof(count));
  255. }
  256. if (buffer.Length - offset < count)
  257. {
  258. throw new ArgumentException("Offset/count out of range");
  259. }
  260. for (int i = 0; i < count; ++i)
  261. {
  262. WriteByte(buffer[offset + i]);
  263. }
  264. }
  265. /// <summary>
  266. /// Write a byte to the stream.
  267. /// </summary>
  268. /// <param name="value">The byte to write to the stream.</param>
  269. public override void WriteByte(byte value)
  270. {
  271. int b = (256 + value) % 256;
  272. if (currentChar != -1)
  273. {
  274. if (currentChar == b)
  275. {
  276. runLength++;
  277. if (runLength > 254)
  278. {
  279. WriteRun();
  280. currentChar = -1;
  281. runLength = 0;
  282. }
  283. }
  284. else
  285. {
  286. WriteRun();
  287. runLength = 1;
  288. currentChar = b;
  289. }
  290. }
  291. else
  292. {
  293. currentChar = b;
  294. runLength++;
  295. }
  296. }
  297. private void MakeMaps()
  298. {
  299. nInUse = 0;
  300. for (int i = 0; i < 256; i++)
  301. {
  302. if (inUse[i])
  303. {
  304. seqToUnseq[nInUse] = (char)i;
  305. unseqToSeq[i] = (char)nInUse;
  306. nInUse++;
  307. }
  308. }
  309. }
  310. /// <summary>
  311. /// Get the number of bytes written to output.
  312. /// </summary>
  313. private void WriteRun()
  314. {
  315. if (last < allowableBlockSize)
  316. {
  317. inUse[currentChar] = true;
  318. for (int i = 0; i < runLength; i++)
  319. {
  320. mCrc.Update(currentChar);
  321. }
  322. switch (runLength)
  323. {
  324. case 1:
  325. last++;
  326. block[last + 1] = (byte)currentChar;
  327. break;
  328. case 2:
  329. last++;
  330. block[last + 1] = (byte)currentChar;
  331. last++;
  332. block[last + 1] = (byte)currentChar;
  333. break;
  334. case 3:
  335. last++;
  336. block[last + 1] = (byte)currentChar;
  337. last++;
  338. block[last + 1] = (byte)currentChar;
  339. last++;
  340. block[last + 1] = (byte)currentChar;
  341. break;
  342. default:
  343. inUse[runLength - 4] = true;
  344. last++;
  345. block[last + 1] = (byte)currentChar;
  346. last++;
  347. block[last + 1] = (byte)currentChar;
  348. last++;
  349. block[last + 1] = (byte)currentChar;
  350. last++;
  351. block[last + 1] = (byte)currentChar;
  352. last++;
  353. block[last + 1] = (byte)(runLength - 4);
  354. break;
  355. }
  356. }
  357. else
  358. {
  359. EndBlock();
  360. InitBlock();
  361. WriteRun();
  362. }
  363. }
  364. /// <summary>
  365. /// Get the number of bytes written to the output.
  366. /// </summary>
  367. public int BytesWritten
  368. {
  369. get { return bytesOut; }
  370. }
  371. /// <summary>
  372. /// Releases the unmanaged resources used by the <see cref="BZip2OutputStream"/> and optionally releases the managed resources.
  373. /// </summary>
  374. /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
  375. override protected void Dispose(bool disposing)
  376. {
  377. try
  378. {
  379. try
  380. {
  381. base.Dispose(disposing);
  382. if (!disposed_)
  383. {
  384. disposed_ = true;
  385. if (runLength > 0)
  386. {
  387. WriteRun();
  388. }
  389. currentChar = -1;
  390. EndBlock();
  391. EndCompression();
  392. Flush();
  393. }
  394. }
  395. finally
  396. {
  397. if (disposing)
  398. {
  399. if (IsStreamOwner)
  400. {
  401. baseStream.Dispose();
  402. }
  403. }
  404. }
  405. }
  406. catch
  407. {
  408. }
  409. }
  410. /// <summary>
  411. /// Flush output buffers
  412. /// </summary>
  413. public override void Flush()
  414. {
  415. baseStream.Flush();
  416. }
  417. private void Initialize()
  418. {
  419. bytesOut = 0;
  420. nBlocksRandomised = 0;
  421. /*--- Write header `magic' bytes indicating file-format == huffmanised,
  422. followed by a digit indicating blockSize100k.
  423. ---*/
  424. BsPutUChar('B');
  425. BsPutUChar('Z');
  426. BsPutUChar('h');
  427. BsPutUChar('0' + blockSize100k);
  428. combinedCRC = 0;
  429. }
  430. private void InitBlock()
  431. {
  432. mCrc.Reset();
  433. last = -1;
  434. for (int i = 0; i < 256; i++)
  435. {
  436. inUse[i] = false;
  437. }
  438. /*--- 20 is just a paranoia constant ---*/
  439. allowableBlockSize = BZip2Constants.BaseBlockSize * blockSize100k - 20;
  440. }
  441. private void EndBlock()
  442. {
  443. if (last < 0)
  444. { // dont do anything for empty files, (makes empty files compatible with original Bzip)
  445. return;
  446. }
  447. blockCRC = unchecked((uint)mCrc.Value);
  448. combinedCRC = (combinedCRC << 1) | (combinedCRC >> 31);
  449. combinedCRC ^= blockCRC;
  450. /*-- sort the block and establish position of original string --*/
  451. DoReversibleTransformation();
  452. /*--
  453. A 6-byte block header, the value chosen arbitrarily
  454. as 0x314159265359 :-). A 32 bit value does not really
  455. give a strong enough guarantee that the value will not
  456. appear by chance in the compressed datastream. Worst-case
  457. probability of this event, for a 900k block, is about
  458. 2.0e-3 for 32 bits, 1.0e-5 for 40 bits and 4.0e-8 for 48 bits.
  459. For a compressed file of size 100Gb -- about 100000 blocks --
  460. only a 48-bit marker will do. NB: normal compression/
  461. decompression do *not* rely on these statistical properties.
  462. They are only important when trying to recover blocks from
  463. damaged files.
  464. --*/
  465. BsPutUChar(0x31);
  466. BsPutUChar(0x41);
  467. BsPutUChar(0x59);
  468. BsPutUChar(0x26);
  469. BsPutUChar(0x53);
  470. BsPutUChar(0x59);
  471. /*-- Now the block's CRC, so it is in a known place. --*/
  472. unchecked
  473. {
  474. BsPutint((int)blockCRC);
  475. }
  476. /*-- Now a single bit indicating randomisation. --*/
  477. if (blockRandomised)
  478. {
  479. BsW(1, 1);
  480. nBlocksRandomised++;
  481. }
  482. else
  483. {
  484. BsW(1, 0);
  485. }
  486. /*-- Finally, block's contents proper. --*/
  487. MoveToFrontCodeAndSend();
  488. }
  489. private void EndCompression()
  490. {
  491. /*--
  492. Now another magic 48-bit number, 0x177245385090, to
  493. indicate the end of the last block. (sqrt(pi), if
  494. you want to know. I did want to use e, but it contains
  495. too much repetition -- 27 18 28 18 28 46 -- for me
  496. to feel statistically comfortable. Call me paranoid.)
  497. --*/
  498. BsPutUChar(0x17);
  499. BsPutUChar(0x72);
  500. BsPutUChar(0x45);
  501. BsPutUChar(0x38);
  502. BsPutUChar(0x50);
  503. BsPutUChar(0x90);
  504. unchecked
  505. {
  506. BsPutint((int)combinedCRC);
  507. }
  508. BsFinishedWithStream();
  509. }
  510. private void BsFinishedWithStream()
  511. {
  512. while (bsLive > 0)
  513. {
  514. int ch = (bsBuff >> 24);
  515. baseStream.WriteByte((byte)ch); // write 8-bit
  516. bsBuff <<= 8;
  517. bsLive -= 8;
  518. bytesOut++;
  519. }
  520. }
  521. private void BsW(int n, int v)
  522. {
  523. while (bsLive >= 8)
  524. {
  525. int ch = (bsBuff >> 24);
  526. unchecked { baseStream.WriteByte((byte)ch); } // write 8-bit
  527. bsBuff <<= 8;
  528. bsLive -= 8;
  529. ++bytesOut;
  530. }
  531. bsBuff |= (v << (32 - bsLive - n));
  532. bsLive += n;
  533. }
  534. private void BsPutUChar(int c)
  535. {
  536. BsW(8, c);
  537. }
  538. private void BsPutint(int u)
  539. {
  540. BsW(8, (u >> 24) & 0xFF);
  541. BsW(8, (u >> 16) & 0xFF);
  542. BsW(8, (u >> 8) & 0xFF);
  543. BsW(8, u & 0xFF);
  544. }
  545. private void BsPutIntVS(int numBits, int c)
  546. {
  547. BsW(numBits, c);
  548. }
  549. private void SendMTFValues()
  550. {
  551. char[][] len = new char[BZip2Constants.GroupCount][];
  552. for (int i = 0; i < BZip2Constants.GroupCount; ++i)
  553. {
  554. len[i] = new char[BZip2Constants.MaximumAlphaSize];
  555. }
  556. int gs, ge, totc, bt, bc, iter;
  557. int nSelectors = 0, alphaSize, minLen, maxLen, selCtr;
  558. int nGroups;
  559. alphaSize = nInUse + 2;
  560. for (int t = 0; t < BZip2Constants.GroupCount; t++)
  561. {
  562. for (int v = 0; v < alphaSize; v++)
  563. {
  564. len[t][v] = (char)GREATER_ICOST;
  565. }
  566. }
  567. /*--- Decide how many coding tables to use ---*/
  568. if (nMTF <= 0)
  569. {
  570. Panic();
  571. }
  572. if (nMTF < 200)
  573. {
  574. nGroups = 2;
  575. }
  576. else if (nMTF < 600)
  577. {
  578. nGroups = 3;
  579. }
  580. else if (nMTF < 1200)
  581. {
  582. nGroups = 4;
  583. }
  584. else if (nMTF < 2400)
  585. {
  586. nGroups = 5;
  587. }
  588. else
  589. {
  590. nGroups = 6;
  591. }
  592. /*--- Generate an initial set of coding tables ---*/
  593. int nPart = nGroups;
  594. int remF = nMTF;
  595. gs = 0;
  596. while (nPart > 0)
  597. {
  598. int tFreq = remF / nPart;
  599. int aFreq = 0;
  600. ge = gs - 1;
  601. while (aFreq < tFreq && ge < alphaSize - 1)
  602. {
  603. ge++;
  604. aFreq += mtfFreq[ge];
  605. }
  606. if (ge > gs && nPart != nGroups && nPart != 1 && ((nGroups - nPart) % 2 == 1))
  607. {
  608. aFreq -= mtfFreq[ge];
  609. ge--;
  610. }
  611. for (int v = 0; v < alphaSize; v++)
  612. {
  613. if (v >= gs && v <= ge)
  614. {
  615. len[nPart - 1][v] = (char)LESSER_ICOST;
  616. }
  617. else
  618. {
  619. len[nPart - 1][v] = (char)GREATER_ICOST;
  620. }
  621. }
  622. nPart--;
  623. gs = ge + 1;
  624. remF -= aFreq;
  625. }
  626. int[][] rfreq = new int[BZip2Constants.GroupCount][];
  627. for (int i = 0; i < BZip2Constants.GroupCount; ++i)
  628. {
  629. rfreq[i] = new int[BZip2Constants.MaximumAlphaSize];
  630. }
  631. int[] fave = new int[BZip2Constants.GroupCount];
  632. short[] cost = new short[BZip2Constants.GroupCount];
  633. /*---
  634. Iterate up to N_ITERS times to improve the tables.
  635. ---*/
  636. for (iter = 0; iter < BZip2Constants.NumberOfIterations; ++iter)
  637. {
  638. for (int t = 0; t < nGroups; ++t)
  639. {
  640. fave[t] = 0;
  641. }
  642. for (int t = 0; t < nGroups; ++t)
  643. {
  644. for (int v = 0; v < alphaSize; ++v)
  645. {
  646. rfreq[t][v] = 0;
  647. }
  648. }
  649. nSelectors = 0;
  650. totc = 0;
  651. gs = 0;
  652. while (true)
  653. {
  654. /*--- Set group start & end marks. --*/
  655. if (gs >= nMTF)
  656. {
  657. break;
  658. }
  659. ge = gs + BZip2Constants.GroupSize - 1;
  660. if (ge >= nMTF)
  661. {
  662. ge = nMTF - 1;
  663. }
  664. /*--
  665. Calculate the cost of this group as coded
  666. by each of the coding tables.
  667. --*/
  668. for (int t = 0; t < nGroups; t++)
  669. {
  670. cost[t] = 0;
  671. }
  672. if (nGroups == 6)
  673. {
  674. short cost0, cost1, cost2, cost3, cost4, cost5;
  675. cost0 = cost1 = cost2 = cost3 = cost4 = cost5 = 0;
  676. for (int i = gs; i <= ge; ++i)
  677. {
  678. short icv = szptr[i];
  679. cost0 += (short)len[0][icv];
  680. cost1 += (short)len[1][icv];
  681. cost2 += (short)len[2][icv];
  682. cost3 += (short)len[3][icv];
  683. cost4 += (short)len[4][icv];
  684. cost5 += (short)len[5][icv];
  685. }
  686. cost[0] = cost0;
  687. cost[1] = cost1;
  688. cost[2] = cost2;
  689. cost[3] = cost3;
  690. cost[4] = cost4;
  691. cost[5] = cost5;
  692. }
  693. else
  694. {
  695. for (int i = gs; i <= ge; ++i)
  696. {
  697. short icv = szptr[i];
  698. for (int t = 0; t < nGroups; t++)
  699. {
  700. cost[t] += (short)len[t][icv];
  701. }
  702. }
  703. }
  704. /*--
  705. Find the coding table which is best for this group,
  706. and record its identity in the selector table.
  707. --*/
  708. bc = 999999999;
  709. bt = -1;
  710. for (int t = 0; t < nGroups; ++t)
  711. {
  712. if (cost[t] < bc)
  713. {
  714. bc = cost[t];
  715. bt = t;
  716. }
  717. }
  718. totc += bc;
  719. fave[bt]++;
  720. selector[nSelectors] = (char)bt;
  721. nSelectors++;
  722. /*--
  723. Increment the symbol frequencies for the selected table.
  724. --*/
  725. for (int i = gs; i <= ge; ++i)
  726. {
  727. ++rfreq[bt][szptr[i]];
  728. }
  729. gs = ge + 1;
  730. }
  731. /*--
  732. Recompute the tables based on the accumulated frequencies.
  733. --*/
  734. for (int t = 0; t < nGroups; ++t)
  735. {
  736. HbMakeCodeLengths(len[t], rfreq[t], alphaSize, 20);
  737. }
  738. }
  739. rfreq = null;
  740. fave = null;
  741. cost = null;
  742. if (!(nGroups < 8))
  743. {
  744. Panic();
  745. }
  746. if (!(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZip2Constants.GroupSize))))
  747. {
  748. Panic();
  749. }
  750. /*--- Compute MTF values for the selectors. ---*/
  751. char[] pos = new char[BZip2Constants.GroupCount];
  752. char ll_i, tmp2, tmp;
  753. for (int i = 0; i < nGroups; i++)
  754. {
  755. pos[i] = (char)i;
  756. }
  757. for (int i = 0; i < nSelectors; i++)
  758. {
  759. ll_i = selector[i];
  760. int j = 0;
  761. tmp = pos[j];
  762. while (ll_i != tmp)
  763. {
  764. j++;
  765. tmp2 = tmp;
  766. tmp = pos[j];
  767. pos[j] = tmp2;
  768. }
  769. pos[0] = tmp;
  770. selectorMtf[i] = (char)j;
  771. }
  772. int[][] code = new int[BZip2Constants.GroupCount][];
  773. for (int i = 0; i < BZip2Constants.GroupCount; ++i)
  774. {
  775. code[i] = new int[BZip2Constants.MaximumAlphaSize];
  776. }
  777. /*--- Assign actual codes for the tables. --*/
  778. for (int t = 0; t < nGroups; t++)
  779. {
  780. minLen = 32;
  781. maxLen = 0;
  782. for (int i = 0; i < alphaSize; i++)
  783. {
  784. if (len[t][i] > maxLen)
  785. {
  786. maxLen = len[t][i];
  787. }
  788. if (len[t][i] < minLen)
  789. {
  790. minLen = len[t][i];
  791. }
  792. }
  793. if (maxLen > 20)
  794. {
  795. Panic();
  796. }
  797. if (minLen < 1)
  798. {
  799. Panic();
  800. }
  801. HbAssignCodes(code[t], len[t], minLen, maxLen, alphaSize);
  802. }
  803. /*--- Transmit the mapping table. ---*/
  804. bool[] inUse16 = new bool[16];
  805. for (int i = 0; i < 16; ++i)
  806. {
  807. inUse16[i] = false;
  808. for (int j = 0; j < 16; ++j)
  809. {
  810. if (inUse[i * 16 + j])
  811. {
  812. inUse16[i] = true;
  813. }
  814. }
  815. }
  816. for (int i = 0; i < 16; ++i)
  817. {
  818. if (inUse16[i])
  819. {
  820. BsW(1, 1);
  821. }
  822. else
  823. {
  824. BsW(1, 0);
  825. }
  826. }
  827. for (int i = 0; i < 16; ++i)
  828. {
  829. if (inUse16[i])
  830. {
  831. for (int j = 0; j < 16; ++j)
  832. {
  833. if (inUse[i * 16 + j])
  834. {
  835. BsW(1, 1);
  836. }
  837. else
  838. {
  839. BsW(1, 0);
  840. }
  841. }
  842. }
  843. }
  844. /*--- Now the selectors. ---*/
  845. BsW(3, nGroups);
  846. BsW(15, nSelectors);
  847. for (int i = 0; i < nSelectors; ++i)
  848. {
  849. for (int j = 0; j < selectorMtf[i]; ++j)
  850. {
  851. BsW(1, 1);
  852. }
  853. BsW(1, 0);
  854. }
  855. /*--- Now the coding tables. ---*/
  856. for (int t = 0; t < nGroups; ++t)
  857. {
  858. int curr = len[t][0];
  859. BsW(5, curr);
  860. for (int i = 0; i < alphaSize; ++i)
  861. {
  862. while (curr < len[t][i])
  863. {
  864. BsW(2, 2);
  865. curr++; /* 10 */
  866. }
  867. while (curr > len[t][i])
  868. {
  869. BsW(2, 3);
  870. curr--; /* 11 */
  871. }
  872. BsW(1, 0);
  873. }
  874. }
  875. /*--- And finally, the block data proper ---*/
  876. selCtr = 0;
  877. gs = 0;
  878. while (true)
  879. {
  880. if (gs >= nMTF)
  881. {
  882. break;
  883. }
  884. ge = gs + BZip2Constants.GroupSize - 1;
  885. if (ge >= nMTF)
  886. {
  887. ge = nMTF - 1;
  888. }
  889. for (int i = gs; i <= ge; i++)
  890. {
  891. BsW(len[selector[selCtr]][szptr[i]], code[selector[selCtr]][szptr[i]]);
  892. }
  893. gs = ge + 1;
  894. ++selCtr;
  895. }
  896. if (!(selCtr == nSelectors))
  897. {
  898. Panic();
  899. }
  900. }
  901. private void MoveToFrontCodeAndSend()
  902. {
  903. BsPutIntVS(24, origPtr);
  904. GenerateMTFValues();
  905. SendMTFValues();
  906. }
  907. private void SimpleSort(int lo, int hi, int d)
  908. {
  909. int i, j, h, bigN, hp;
  910. int v;
  911. bigN = hi - lo + 1;
  912. if (bigN < 2)
  913. {
  914. return;
  915. }
  916. hp = 0;
  917. while (increments[hp] < bigN)
  918. {
  919. hp++;
  920. }
  921. hp--;
  922. for (; hp >= 0; hp--)
  923. {
  924. h = increments[hp];
  925. i = lo + h;
  926. while (true)
  927. {
  928. /*-- copy 1 --*/
  929. if (i > hi)
  930. break;
  931. v = zptr[i];
  932. j = i;
  933. while (FullGtU(zptr[j - h] + d, v + d))
  934. {
  935. zptr[j] = zptr[j - h];
  936. j = j - h;
  937. if (j <= (lo + h - 1))
  938. break;
  939. }
  940. zptr[j] = v;
  941. i++;
  942. /*-- copy 2 --*/
  943. if (i > hi)
  944. {
  945. break;
  946. }
  947. v = zptr[i];
  948. j = i;
  949. while (FullGtU(zptr[j - h] + d, v + d))
  950. {
  951. zptr[j] = zptr[j - h];
  952. j = j - h;
  953. if (j <= (lo + h - 1))
  954. {
  955. break;
  956. }
  957. }
  958. zptr[j] = v;
  959. i++;
  960. /*-- copy 3 --*/
  961. if (i > hi)
  962. {
  963. break;
  964. }
  965. v = zptr[i];
  966. j = i;
  967. while (FullGtU(zptr[j - h] + d, v + d))
  968. {
  969. zptr[j] = zptr[j - h];
  970. j = j - h;
  971. if (j <= (lo + h - 1))
  972. {
  973. break;
  974. }
  975. }
  976. zptr[j] = v;
  977. i++;
  978. if (workDone > workLimit && firstAttempt)
  979. {
  980. return;
  981. }
  982. }
  983. }
  984. }
  985. private void Vswap(int p1, int p2, int n)
  986. {
  987. int temp = 0;
  988. while (n > 0)
  989. {
  990. temp = zptr[p1];
  991. zptr[p1] = zptr[p2];
  992. zptr[p2] = temp;
  993. p1++;
  994. p2++;
  995. n--;
  996. }
  997. }
  998. private void QSort3(int loSt, int hiSt, int dSt)
  999. {
  1000. int unLo, unHi, ltLo, gtHi, med, n, m;
  1001. int lo, hi, d;
  1002. StackElement[] stack = new StackElement[QSORT_STACK_SIZE];
  1003. int sp = 0;
  1004. stack[sp].ll = loSt;
  1005. stack[sp].hh = hiSt;
  1006. stack[sp].dd = dSt;
  1007. sp++;
  1008. while (sp > 0)
  1009. {
  1010. if (sp >= QSORT_STACK_SIZE)
  1011. {
  1012. Panic();
  1013. }
  1014. sp--;
  1015. lo = stack[sp].ll;
  1016. hi = stack[sp].hh;
  1017. d = stack[sp].dd;
  1018. if (hi - lo < SMALL_THRESH || d > DEPTH_THRESH)
  1019. {
  1020. SimpleSort(lo, hi, d);
  1021. if (workDone > workLimit && firstAttempt)
  1022. {
  1023. return;
  1024. }
  1025. continue;
  1026. }
  1027. med = Med3(block[zptr[lo] + d + 1],
  1028. block[zptr[hi] + d + 1],
  1029. block[zptr[(lo + hi) >> 1] + d + 1]);
  1030. unLo = ltLo = lo;
  1031. unHi = gtHi = hi;
  1032. while (true)
  1033. {
  1034. while (true)
  1035. {
  1036. if (unLo > unHi)
  1037. {
  1038. break;
  1039. }
  1040. n = ((int)block[zptr[unLo] + d + 1]) - med;
  1041. if (n == 0)
  1042. {
  1043. int temp = zptr[unLo];
  1044. zptr[unLo] = zptr[ltLo];
  1045. zptr[ltLo] = temp;
  1046. ltLo++;
  1047. unLo++;
  1048. continue;
  1049. }
  1050. if (n > 0)
  1051. {
  1052. break;
  1053. }
  1054. unLo++;
  1055. }
  1056. while (true)
  1057. {
  1058. if (unLo > unHi)
  1059. {
  1060. break;
  1061. }
  1062. n = ((int)block[zptr[unHi] + d + 1]) - med;
  1063. if (n == 0)
  1064. {
  1065. int temp = zptr[unHi];
  1066. zptr[unHi] = zptr[gtHi];
  1067. zptr[gtHi] = temp;
  1068. gtHi--;
  1069. unHi--;
  1070. continue;
  1071. }
  1072. if (n < 0)
  1073. {
  1074. break;
  1075. }
  1076. unHi--;
  1077. }
  1078. if (unLo > unHi)
  1079. {
  1080. break;
  1081. }
  1082. {
  1083. int temp = zptr[unLo];
  1084. zptr[unLo] = zptr[unHi];
  1085. zptr[unHi] = temp;
  1086. unLo++;
  1087. unHi--;
  1088. }
  1089. }
  1090. if (gtHi < ltLo)
  1091. {
  1092. stack[sp].ll = lo;
  1093. stack[sp].hh = hi;
  1094. stack[sp].dd = d + 1;
  1095. sp++;
  1096. continue;
  1097. }
  1098. n = ((ltLo - lo) < (unLo - ltLo)) ? (ltLo - lo) : (unLo - ltLo);
  1099. Vswap(lo, unLo - n, n);
  1100. m = ((hi - gtHi) < (gtHi - unHi)) ? (hi - gtHi) : (gtHi - unHi);
  1101. Vswap(unLo, hi - m + 1, m);
  1102. n = lo + unLo - ltLo - 1;
  1103. m = hi - (gtHi - unHi) + 1;
  1104. stack[sp].ll = lo;
  1105. stack[sp].hh = n;
  1106. stack[sp].dd = d;
  1107. sp++;
  1108. stack[sp].ll = n + 1;
  1109. stack[sp].hh = m - 1;
  1110. stack[sp].dd = d + 1;
  1111. sp++;
  1112. stack[sp].ll = m;
  1113. stack[sp].hh = hi;
  1114. stack[sp].dd = d;
  1115. sp++;
  1116. }
  1117. }
  1118. private void MainSort()
  1119. {
  1120. int i, j, ss, sb;
  1121. int[] runningOrder = new int[256];
  1122. int[] copy = new int[256];
  1123. bool[] bigDone = new bool[256];
  1124. int c1, c2;
  1125. int numQSorted;
  1126. /*--
  1127. In the various block-sized structures, live data runs
  1128. from 0 to last+NUM_OVERSHOOT_BYTES inclusive. First,
  1129. set up the overshoot area for block.
  1130. --*/
  1131. // if (verbosity >= 4) fprintf ( stderr, " sort initialise ...\n" );
  1132. for (i = 0; i < BZip2Constants.OvershootBytes; i++)
  1133. {
  1134. block[last + i + 2] = block[(i % (last + 1)) + 1];
  1135. }
  1136. for (i = 0; i <= last + BZip2Constants.OvershootBytes; i++)
  1137. {
  1138. quadrant[i] = 0;
  1139. }
  1140. block[0] = (byte)(block[last + 1]);
  1141. if (last < 4000)
  1142. {
  1143. /*--
  1144. Use simpleSort(), since the full sorting mechanism
  1145. has quite a large constant overhead.
  1146. --*/
  1147. for (i = 0; i <= last; i++)
  1148. {
  1149. zptr[i] = i;
  1150. }
  1151. firstAttempt = false;
  1152. workDone = workLimit = 0;
  1153. SimpleSort(0, last, 0);
  1154. }
  1155. else
  1156. {
  1157. numQSorted = 0;
  1158. for (i = 0; i <= 255; i++)
  1159. {
  1160. bigDone[i] = false;
  1161. }
  1162. for (i = 0; i <= 65536; i++)
  1163. {
  1164. ftab[i] = 0;
  1165. }
  1166. c1 = block[0];
  1167. for (i = 0; i <= last; i++)
  1168. {
  1169. c2 = block[i + 1];
  1170. ftab[(c1 << 8) + c2]++;
  1171. c1 = c2;
  1172. }
  1173. for (i = 1; i <= 65536; i++)
  1174. {
  1175. ftab[i] += ftab[i - 1];
  1176. }
  1177. c1 = block[1];
  1178. for (i = 0; i < last; i++)
  1179. {
  1180. c2 = block[i + 2];
  1181. j = (c1 << 8) + c2;
  1182. c1 = c2;
  1183. ftab[j]--;
  1184. zptr[ftab[j]] = i;
  1185. }
  1186. j = ((block[last + 1]) << 8) + (block[1]);
  1187. ftab[j]--;
  1188. zptr[ftab[j]] = last;
  1189. /*--
  1190. Now ftab contains the first loc of every small bucket.
  1191. Calculate the running order, from smallest to largest
  1192. big bucket.
  1193. --*/
  1194. for (i = 0; i <= 255; i++)
  1195. {
  1196. runningOrder[i] = i;
  1197. }
  1198. int vv;
  1199. int h = 1;
  1200. do
  1201. {
  1202. h = 3 * h + 1;
  1203. } while (h <= 256);
  1204. do
  1205. {
  1206. h = h / 3;
  1207. for (i = h; i <= 255; i++)
  1208. {
  1209. vv = runningOrder[i];
  1210. j = i;
  1211. while ((ftab[((runningOrder[j - h]) + 1) << 8] - ftab[(runningOrder[j - h]) << 8]) > (ftab[((vv) + 1) << 8] - ftab[(vv) << 8]))
  1212. {
  1213. runningOrder[j] = runningOrder[j - h];
  1214. j = j - h;
  1215. if (j <= (h - 1))
  1216. {
  1217. break;
  1218. }
  1219. }
  1220. runningOrder[j] = vv;
  1221. }
  1222. } while (h != 1);
  1223. /*--
  1224. The main sorting loop.
  1225. --*/
  1226. for (i = 0; i <= 255; i++)
  1227. {
  1228. /*--
  1229. Process big buckets, starting with the least full.
  1230. --*/
  1231. ss = runningOrder[i];
  1232. /*--
  1233. Complete the big bucket [ss] by quicksorting
  1234. any unsorted small buckets [ss, j]. Hopefully
  1235. previous pointer-scanning phases have already
  1236. completed many of the small buckets [ss, j], so
  1237. we don't have to sort them at all.
  1238. --*/
  1239. for (j = 0; j <= 255; j++)
  1240. {
  1241. sb = (ss << 8) + j;
  1242. if (!((ftab[sb] & SETMASK) == SETMASK))
  1243. {
  1244. int lo = ftab[sb] & CLEARMASK;
  1245. int hi = (ftab[sb + 1] & CLEARMASK) - 1;
  1246. if (hi > lo)
  1247. {
  1248. QSort3(lo, hi, 2);
  1249. numQSorted += (hi - lo + 1);
  1250. if (workDone > workLimit && firstAttempt)
  1251. {
  1252. return;
  1253. }
  1254. }
  1255. ftab[sb] |= SETMASK;
  1256. }
  1257. }
  1258. /*--
  1259. The ss big bucket is now done. Record this fact,
  1260. and update the quadrant descriptors. Remember to
  1261. update quadrants in the overshoot area too, if
  1262. necessary. The "if (i < 255)" test merely skips
  1263. this updating for the last bucket processed, since
  1264. updating for the last bucket is pointless.
  1265. --*/
  1266. bigDone[ss] = true;
  1267. if (i < 255)
  1268. {
  1269. int bbStart = ftab[ss << 8] & CLEARMASK;
  1270. int bbSize = (ftab[(ss + 1) << 8] & CLEARMASK) - bbStart;
  1271. int shifts = 0;
  1272. while ((bbSize >> shifts) > 65534)
  1273. {
  1274. shifts++;
  1275. }
  1276. for (j = 0; j < bbSize; j++)
  1277. {
  1278. int a2update = zptr[bbStart + j];
  1279. int qVal = (j >> shifts);
  1280. quadrant[a2update] = qVal;
  1281. if (a2update < BZip2Constants.OvershootBytes)
  1282. {
  1283. quadrant[a2update + last + 1] = qVal;
  1284. }
  1285. }
  1286. if (!(((bbSize - 1) >> shifts) <= 65535))
  1287. {
  1288. Panic();
  1289. }
  1290. }
  1291. /*--
  1292. Now scan this big bucket so as to synthesise the
  1293. sorted order for small buckets [t, ss] for all t != ss.
  1294. --*/
  1295. for (j = 0; j <= 255; j++)
  1296. {
  1297. copy[j] = ftab[(j << 8) + ss] & CLEARMASK;
  1298. }
  1299. for (j = ftab[ss << 8] & CLEARMASK; j < (ftab[(ss + 1) << 8] & CLEARMASK); j++)
  1300. {
  1301. c1 = block[zptr[j]];
  1302. if (!bigDone[c1])
  1303. {
  1304. zptr[copy[c1]] = zptr[j] == 0 ? last : zptr[j] - 1;
  1305. copy[c1]++;
  1306. }
  1307. }
  1308. for (j = 0; j <= 255; j++)
  1309. {
  1310. ftab[(j << 8) + ss] |= SETMASK;
  1311. }
  1312. }
  1313. }
  1314. }
  1315. private void RandomiseBlock()
  1316. {
  1317. int i;
  1318. int rNToGo = 0;
  1319. int rTPos = 0;
  1320. for (i = 0; i < 256; i++)
  1321. {
  1322. inUse[i] = false;
  1323. }
  1324. for (i = 0; i <= last; i++)
  1325. {
  1326. if (rNToGo == 0)
  1327. {
  1328. rNToGo = (int)BZip2Constants.RandomNumbers[rTPos];
  1329. rTPos++;
  1330. if (rTPos == 512)
  1331. {
  1332. rTPos = 0;
  1333. }
  1334. }
  1335. rNToGo--;
  1336. block[i + 1] ^= (byte)((rNToGo == 1) ? 1 : 0);
  1337. // handle 16 bit signed numbers
  1338. block[i + 1] &= 0xFF;
  1339. inUse[block[i + 1]] = true;
  1340. }
  1341. }
  1342. private void DoReversibleTransformation()
  1343. {
  1344. workLimit = workFactor * last;
  1345. workDone = 0;
  1346. blockRandomised = false;
  1347. firstAttempt = true;
  1348. MainSort();
  1349. if (workDone > workLimit && firstAttempt)
  1350. {
  1351. RandomiseBlock();
  1352. workLimit = workDone = 0;
  1353. blockRandomised = true;
  1354. firstAttempt = false;
  1355. MainSort();
  1356. }
  1357. origPtr = -1;
  1358. for (int i = 0; i <= last; i++)
  1359. {
  1360. if (zptr[i] == 0)
  1361. {
  1362. origPtr = i;
  1363. break;
  1364. }
  1365. }
  1366. if (origPtr == -1)
  1367. {
  1368. Panic();
  1369. }
  1370. }
  1371. private bool FullGtU(int i1, int i2)
  1372. {
  1373. int k;
  1374. byte c1, c2;
  1375. int s1, s2;
  1376. c1 = block[i1 + 1];
  1377. c2 = block[i2 + 1];
  1378. if (c1 != c2)
  1379. {
  1380. return c1 > c2;
  1381. }
  1382. i1++;
  1383. i2++;
  1384. c1 = block[i1 + 1];
  1385. c2 = block[i2 + 1];
  1386. if (c1 != c2)
  1387. {
  1388. return c1 > c2;
  1389. }
  1390. i1++;
  1391. i2++;
  1392. c1 = block[i1 + 1];
  1393. c2 = block[i2 + 1];
  1394. if (c1 != c2)
  1395. {
  1396. return c1 > c2;
  1397. }
  1398. i1++;
  1399. i2++;
  1400. c1 = block[i1 + 1];
  1401. c2 = block[i2 + 1];
  1402. if (c1 != c2)
  1403. {
  1404. return c1 > c2;
  1405. }
  1406. i1++;
  1407. i2++;
  1408. c1 = block[i1 + 1];
  1409. c2 = block[i2 + 1];
  1410. if (c1 != c2)
  1411. {
  1412. return c1 > c2;
  1413. }
  1414. i1++;
  1415. i2++;
  1416. c1 = block[i1 + 1];
  1417. c2 = block[i2 + 1];
  1418. if (c1 != c2)
  1419. {
  1420. return c1 > c2;
  1421. }
  1422. i1++;
  1423. i2++;
  1424. k = last + 1;
  1425. do
  1426. {
  1427. c1 = block[i1 + 1];
  1428. c2 = block[i2 + 1];
  1429. if (c1 != c2)
  1430. {
  1431. return c1 > c2;
  1432. }
  1433. s1 = quadrant[i1];
  1434. s2 = quadrant[i2];
  1435. if (s1 != s2)
  1436. {
  1437. return s1 > s2;
  1438. }
  1439. i1++;
  1440. i2++;
  1441. c1 = block[i1 + 1];
  1442. c2 = block[i2 + 1];
  1443. if (c1 != c2)
  1444. {
  1445. return c1 > c2;
  1446. }
  1447. s1 = quadrant[i1];
  1448. s2 = quadrant[i2];
  1449. if (s1 != s2)
  1450. {
  1451. return s1 > s2;
  1452. }
  1453. i1++;
  1454. i2++;
  1455. c1 = block[i1 + 1];
  1456. c2 = block[i2 + 1];
  1457. if (c1 != c2)
  1458. {
  1459. return c1 > c2;
  1460. }
  1461. s1 = quadrant[i1];
  1462. s2 = quadrant[i2];
  1463. if (s1 != s2)
  1464. {
  1465. return s1 > s2;
  1466. }
  1467. i1++;
  1468. i2++;
  1469. c1 = block[i1 + 1];
  1470. c2 = block[i2 + 1];
  1471. if (c1 != c2)
  1472. {
  1473. return c1 > c2;
  1474. }
  1475. s1 = quadrant[i1];
  1476. s2 = quadrant[i2];
  1477. if (s1 != s2)
  1478. {
  1479. return s1 > s2;
  1480. }
  1481. i1++;
  1482. i2++;
  1483. if (i1 > last)
  1484. {
  1485. i1 -= last;
  1486. i1--;
  1487. }
  1488. if (i2 > last)
  1489. {
  1490. i2 -= last;
  1491. i2--;
  1492. }
  1493. k -= 4;
  1494. ++workDone;
  1495. } while (k >= 0);
  1496. return false;
  1497. }
  1498. private void AllocateCompressStructures()
  1499. {
  1500. int n = BZip2Constants.BaseBlockSize * blockSize100k;
  1501. block = new byte[(n + 1 + BZip2Constants.OvershootBytes)];
  1502. quadrant = new int[(n + BZip2Constants.OvershootBytes)];
  1503. zptr = new int[n];
  1504. ftab = new int[65537];
  1505. if (block == null || quadrant == null || zptr == null || ftab == null)
  1506. {
  1507. // int totalDraw = (n + 1 + NUM_OVERSHOOT_BYTES) + (n + NUM_OVERSHOOT_BYTES) + n + 65537;
  1508. // compressOutOfMemory ( totalDraw, n );
  1509. }
  1510. /*
  1511. The back end needs a place to store the MTF values
  1512. whilst it calculates the coding tables. We could
  1513. put them in the zptr array. However, these values
  1514. will fit in a short, so we overlay szptr at the
  1515. start of zptr, in the hope of reducing the number
  1516. of cache misses induced by the multiple traversals
  1517. of the MTF values when calculating coding tables.
  1518. Seems to improve compression speed by about 1%.
  1519. */
  1520. // szptr = zptr;
  1521. szptr = new short[2 * n];
  1522. }
  1523. private void GenerateMTFValues()
  1524. {
  1525. char[] yy = new char[256];
  1526. int i, j;
  1527. char tmp;
  1528. char tmp2;
  1529. int zPend;
  1530. int wr;
  1531. int EOB;
  1532. MakeMaps();
  1533. EOB = nInUse + 1;
  1534. for (i = 0; i <= EOB; i++)
  1535. {
  1536. mtfFreq[i] = 0;
  1537. }
  1538. wr = 0;
  1539. zPend = 0;
  1540. for (i = 0; i < nInUse; i++)
  1541. {
  1542. yy[i] = (char)i;
  1543. }
  1544. for (i = 0; i <= last; i++)
  1545. {
  1546. char ll_i;
  1547. ll_i = unseqToSeq[block[zptr[i]]];
  1548. j = 0;
  1549. tmp = yy[j];
  1550. while (ll_i != tmp)
  1551. {
  1552. j++;
  1553. tmp2 = tmp;
  1554. tmp = yy[j];
  1555. yy[j] = tmp2;
  1556. }
  1557. yy[0] = tmp;
  1558. if (j == 0)
  1559. {
  1560. zPend++;
  1561. }
  1562. else
  1563. {
  1564. if (zPend > 0)
  1565. {
  1566. zPend--;
  1567. while (true)
  1568. {
  1569. switch (zPend % 2)
  1570. {
  1571. case 0:
  1572. szptr[wr] = (short)BZip2Constants.RunA;
  1573. wr++;
  1574. mtfFreq[BZip2Constants.RunA]++;
  1575. break;
  1576. case 1:
  1577. szptr[wr] = (short)BZip2Constants.RunB;
  1578. wr++;
  1579. mtfFreq[BZip2Constants.RunB]++;
  1580. break;
  1581. }
  1582. if (zPend < 2)
  1583. {
  1584. break;
  1585. }
  1586. zPend = (zPend - 2) / 2;
  1587. }
  1588. zPend = 0;
  1589. }
  1590. szptr[wr] = (short)(j + 1);
  1591. wr++;
  1592. mtfFreq[j + 1]++;
  1593. }
  1594. }
  1595. if (zPend > 0)
  1596. {
  1597. zPend--;
  1598. while (true)
  1599. {
  1600. switch (zPend % 2)
  1601. {
  1602. case 0:
  1603. szptr[wr] = (short)BZip2Constants.RunA;
  1604. wr++;
  1605. mtfFreq[BZip2Constants.RunA]++;
  1606. break;
  1607. case 1:
  1608. szptr[wr] = (short)BZip2Constants.RunB;
  1609. wr++;
  1610. mtfFreq[BZip2Constants.RunB]++;
  1611. break;
  1612. }
  1613. if (zPend < 2)
  1614. {
  1615. break;
  1616. }
  1617. zPend = (zPend - 2) / 2;
  1618. }
  1619. }
  1620. szptr[wr] = (short)EOB;
  1621. wr++;
  1622. mtfFreq[EOB]++;
  1623. nMTF = wr;
  1624. }
  1625. private static void Panic()
  1626. {
  1627. throw new BZip2Exception("BZip2 output stream panic");
  1628. }
  1629. private static void HbMakeCodeLengths(char[] len, int[] freq, int alphaSize, int maxLen)
  1630. {
  1631. /*--
  1632. Nodes and heap entries run from 1. Entry 0
  1633. for both the heap and nodes is a sentinel.
  1634. --*/
  1635. int nNodes, nHeap, n1, n2, j, k;
  1636. bool tooLong;
  1637. int[] heap = new int[BZip2Constants.MaximumAlphaSize + 2];
  1638. int[] weight = new int[BZip2Constants.MaximumAlphaSize * 2];
  1639. int[] parent = new int[BZip2Constants.MaximumAlphaSize * 2];
  1640. for (int i = 0; i < alphaSize; ++i)
  1641. {
  1642. weight[i + 1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
  1643. }
  1644. while (true)
  1645. {
  1646. nNodes = alphaSize;
  1647. nHeap = 0;
  1648. heap[0] = 0;
  1649. weight[0] = 0;
  1650. parent[0] = -2;
  1651. for (int i = 1; i <= alphaSize; ++i)
  1652. {
  1653. parent[i] = -1;
  1654. nHeap++;
  1655. heap[nHeap] = i;
  1656. int zz = nHeap;
  1657. int tmp = heap[zz];
  1658. while (weight[tmp] < weight[heap[zz >> 1]])
  1659. {
  1660. heap[zz] = heap[zz >> 1];
  1661. zz >>= 1;
  1662. }
  1663. heap[zz] = tmp;
  1664. }
  1665. if (!(nHeap < (BZip2Constants.MaximumAlphaSize + 2)))
  1666. {
  1667. Panic();
  1668. }
  1669. while (nHeap > 1)
  1670. {
  1671. n1 = heap[1];
  1672. heap[1] = heap[nHeap];
  1673. nHeap--;
  1674. int zz = 1;
  1675. int yy = 0;
  1676. int tmp = heap[zz];
  1677. while (true)
  1678. {
  1679. yy = zz << 1;
  1680. if (yy > nHeap)
  1681. {
  1682. break;
  1683. }
  1684. if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]])
  1685. {
  1686. yy++;
  1687. }
  1688. if (weight[tmp] < weight[heap[yy]])
  1689. {
  1690. break;
  1691. }
  1692. heap[zz] = heap[yy];
  1693. zz = yy;
  1694. }
  1695. heap[zz] = tmp;
  1696. n2 = heap[1];
  1697. heap[1] = heap[nHeap];
  1698. nHeap--;
  1699. zz = 1;
  1700. yy = 0;
  1701. tmp = heap[zz];
  1702. while (true)
  1703. {
  1704. yy = zz << 1;
  1705. if (yy > nHeap)
  1706. {
  1707. break;
  1708. }
  1709. if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]])
  1710. {
  1711. yy++;
  1712. }
  1713. if (weight[tmp] < weight[heap[yy]])
  1714. {
  1715. break;
  1716. }
  1717. heap[zz] = heap[yy];
  1718. zz = yy;
  1719. }
  1720. heap[zz] = tmp;
  1721. nNodes++;
  1722. parent[n1] = parent[n2] = nNodes;
  1723. weight[nNodes] = (int)((weight[n1] & 0xffffff00) + (weight[n2] & 0xffffff00)) |
  1724. (int)(1 + (((weight[n1] & 0x000000ff) > (weight[n2] & 0x000000ff)) ? (weight[n1] & 0x000000ff) : (weight[n2] & 0x000000ff)));
  1725. parent[nNodes] = -1;
  1726. nHeap++;
  1727. heap[nHeap] = nNodes;
  1728. zz = nHeap;
  1729. tmp = heap[zz];
  1730. while (weight[tmp] < weight[heap[zz >> 1]])
  1731. {
  1732. heap[zz] = heap[zz >> 1];
  1733. zz >>= 1;
  1734. }
  1735. heap[zz] = tmp;
  1736. }
  1737. if (!(nNodes < (BZip2Constants.MaximumAlphaSize * 2)))
  1738. {
  1739. Panic();
  1740. }
  1741. tooLong = false;
  1742. for (int i = 1; i <= alphaSize; ++i)
  1743. {
  1744. j = 0;
  1745. k = i;
  1746. while (parent[k] >= 0)
  1747. {
  1748. k = parent[k];
  1749. j++;
  1750. }
  1751. len[i - 1] = (char)j;
  1752. tooLong |= j > maxLen;
  1753. }
  1754. if (!tooLong)
  1755. {
  1756. break;
  1757. }
  1758. for (int i = 1; i < alphaSize; ++i)
  1759. {
  1760. j = weight[i] >> 8;
  1761. j = 1 + (j / 2);
  1762. weight[i] = j << 8;
  1763. }
  1764. }
  1765. }
  1766. private static void HbAssignCodes(int[] code, char[] length, int minLen, int maxLen, int alphaSize)
  1767. {
  1768. int vec = 0;
  1769. for (int n = minLen; n <= maxLen; ++n)
  1770. {
  1771. for (int i = 0; i < alphaSize; ++i)
  1772. {
  1773. if (length[i] == n)
  1774. {
  1775. code[i] = vec;
  1776. ++vec;
  1777. }
  1778. }
  1779. vec <<= 1;
  1780. }
  1781. }
  1782. private static byte Med3(byte a, byte b, byte c)
  1783. {
  1784. byte t;
  1785. if (a > b)
  1786. {
  1787. t = a;
  1788. a = b;
  1789. b = t;
  1790. }
  1791. if (b > c)
  1792. {
  1793. t = b;
  1794. b = c;
  1795. c = t;
  1796. }
  1797. if (a > b)
  1798. {
  1799. b = a;
  1800. }
  1801. return b;
  1802. }
  1803. private struct StackElement
  1804. {
  1805. public int ll;
  1806. public int hh;
  1807. public int dd;
  1808. }
  1809. }
  1810. }