using System.IO; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Apache.Bzip2; public class CBZip2OutputStream : Stream { internal class StackElem { internal int ll; internal int hh; internal int dd; } protected const int SETMASK = 2097152; protected const int CLEARMASK = -2097153; protected const int GREATER_ICOST = 15; protected const int LESSER_ICOST = 0; protected const int SMALL_THRESH = 20; protected const int DEPTH_THRESH = 10; protected const int QSORT_STACK_SIZE = 1000; private bool finished; private int last; private int origPtr; private int blockSize100k; private bool blockRandomised; private int bytesOut; private int bsBuff; private int bsLive; private CRC mCrc = new CRC(); private bool[] inUse = new bool[256]; private int nInUse; private char[] seqToUnseq = new char[256]; private char[] unseqToSeq = new char[256]; private char[] selector = new char[18002]; private char[] selectorMtf = new char[18002]; private char[] block; private int[] quadrant; private int[] zptr; private short[] szptr; private int[] ftab; private int nMTF; private int[] mtfFreq = new int[258]; private int workFactor; private int workDone; private int workLimit; private bool firstAttempt; private int nBlocksRandomised; private int currentChar = -1; private int runLength = 0; private bool closed = false; private int blockCRC; private int combinedCRC; private int allowableBlockSize; private Stream bsStream; private int[] incs = new int[14] { 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484 }; public override bool CanRead => false; public override bool CanSeek => false; public override bool CanWrite => true; public override long Length => 0L; public override long Position { get { return 0L; } set { } } private static void Panic() { } private void MakeMaps() { nInUse = 0; for (int i = 0; i < 256; i++) { if (inUse[i]) { seqToUnseq[nInUse] = (char)i; unseqToSeq[i] = (char)nInUse; nInUse++; } } } protected static void HbMakeCodeLengths(char[] len, int[] freq, int alphaSize, int maxLen) { int[] array = new int[260]; int[] array2 = new int[516]; int[] array3 = new int[516]; for (int i = 0; i < alphaSize; i++) { array2[i + 1] = ((freq[i] == 0) ? 1 : freq[i]) << 8; } while (true) { int num = alphaSize; int num2 = 0; array[0] = 0; array2[0] = 0; array3[0] = -2; for (int i = 1; i <= alphaSize; i++) { array3[i] = -1; num2++; array[num2] = i; int num3 = num2; int num4 = array[num3]; while (array2[num4] < array2[array[num3 >> 1]]) { array[num3] = array[num3 >> 1]; num3 >>= 1; } array[num3] = num4; } if (num2 >= 260) { Panic(); } while (num2 > 1) { int num5 = array[1]; array[1] = array[num2]; num2--; int num6 = 0; int num7 = 0; int num8 = 0; num6 = 1; num8 = array[num6]; while (true) { num7 = num6 << 1; if (num7 > num2) { break; } if (num7 < num2 && array2[array[num7 + 1]] < array2[array[num7]]) { num7++; } if (array2[num8] < array2[array[num7]]) { break; } array[num6] = array[num7]; num6 = num7; } array[num6] = num8; int num9 = array[1]; array[1] = array[num2]; num2--; int num10 = 0; int num11 = 0; int num12 = 0; num10 = 1; num12 = array[num10]; while (true) { num11 = num10 << 1; if (num11 > num2) { break; } if (num11 < num2 && array2[array[num11 + 1]] < array2[array[num11]]) { num11++; } if (array2[num12] < array2[array[num11]]) { break; } array[num10] = array[num11]; num10 = num11; } array[num10] = num12; num++; array3[num5] = (array3[num9] = num); array2[num] = (int)((array2[num5] & 0xFFFFFF00u) + (array2[num9] & 0xFFFFFF00u)) | (1 + (((array2[num5] & 0xFF) > (array2[num9] & 0xFF)) ? (array2[num5] & 0xFF) : (array2[num9] & 0xFF))); array3[num] = -1; num2++; array[num2] = num; int num13 = 0; int num14 = 0; num13 = num2; num14 = array[num13]; while (array2[num14] < array2[array[num13 >> 1]]) { array[num13] = array[num13 >> 1]; num13 >>= 1; } array[num13] = num14; } if (num >= 516) { Panic(); } bool flag = false; for (int i = 1; i <= alphaSize; i++) { int num15 = 0; int num16 = i; while (array3[num16] >= 0) { num16 = array3[num16]; num15++; } len[i - 1] = (char)num15; if (num15 > maxLen) { flag = true; } } if (!flag) { break; } for (int i = 1; i < alphaSize; i++) { int num15 = array2[i] >> 8; num15 = 1 + num15 / 2; array2[i] = num15 << 8; } } } public CBZip2OutputStream(Stream inStream) : this(inStream, 9) { } public CBZip2OutputStream(Stream inStream, int inBlockSize) { block = null; quadrant = null; zptr = null; ftab = null; inStream.WriteByte(66); inStream.WriteByte(90); BsSetStream(inStream); workFactor = 50; if (inBlockSize > 9) { inBlockSize = 9; } if (inBlockSize < 1) { inBlockSize = 1; } blockSize100k = inBlockSize; AllocateCompressStructures(); Initialize(); InitBlock(); } public override void WriteByte(byte bv) { int num = (256 + bv) % 256; if (currentChar != -1) { if (currentChar == num) { runLength++; if (runLength > 254) { WriteRun(); currentChar = -1; runLength = 0; } } else { WriteRun(); runLength = 1; currentChar = num; } } else { currentChar = num; runLength++; } } private void WriteRun() { if (last < allowableBlockSize) { inUse[currentChar] = true; for (int i = 0; i < runLength; i++) { mCrc.UpdateCRC((ushort)currentChar); } switch (runLength) { case 1: last++; block[last + 1] = (char)currentChar; break; case 2: last++; block[last + 1] = (char)currentChar; last++; block[last + 1] = (char)currentChar; break; case 3: last++; block[last + 1] = (char)currentChar; last++; block[last + 1] = (char)currentChar; last++; block[last + 1] = (char)currentChar; break; default: inUse[runLength - 4] = true; last++; block[last + 1] = (char)currentChar; last++; block[last + 1] = (char)currentChar; last++; block[last + 1] = (char)currentChar; last++; block[last + 1] = (char)currentChar; last++; block[last + 1] = (char)(runLength - 4); break; } } else { EndBlock(); InitBlock(); WriteRun(); } } public override void Close() { if (!closed) { Finish(); closed = true; Platform.Dispose(bsStream); base.Close(); } } public void Finish() { if (!finished) { if (runLength > 0) { WriteRun(); } currentChar = -1; EndBlock(); EndCompression(); finished = true; Flush(); } } public override void Flush() { bsStream.Flush(); } private void Initialize() { bytesOut = 0; nBlocksRandomised = 0; BsPutUChar(104); BsPutUChar(48 + blockSize100k); combinedCRC = 0; } private void InitBlock() { mCrc.InitialiseCRC(); last = -1; for (int i = 0; i < 256; i++) { inUse[i] = false; } allowableBlockSize = 100000 * blockSize100k - 20; } private void EndBlock() { blockCRC = mCrc.GetFinalCRC(); combinedCRC = (combinedCRC << 1) | (combinedCRC >>> 31); combinedCRC ^= blockCRC; DoReversibleTransformation(); BsPutUChar(49); BsPutUChar(65); BsPutUChar(89); BsPutUChar(38); BsPutUChar(83); BsPutUChar(89); BsPutint(blockCRC); if (blockRandomised) { BsW(1, 1); nBlocksRandomised++; } else { BsW(1, 0); } MoveToFrontCodeAndSend(); } private void EndCompression() { BsPutUChar(23); BsPutUChar(114); BsPutUChar(69); BsPutUChar(56); BsPutUChar(80); BsPutUChar(144); BsPutint(combinedCRC); BsFinishedWithStream(); } private void HbAssignCodes(int[] code, char[] length, int minLen, int maxLen, int alphaSize) { int num = 0; for (int i = minLen; i <= maxLen; i++) { for (int j = 0; j < alphaSize; j++) { if (length[j] == i) { code[j] = num; num++; } } num <<= 1; } } private void BsSetStream(Stream f) { bsStream = f; bsLive = 0; bsBuff = 0; bytesOut = 0; } private void BsFinishedWithStream() { while (bsLive > 0) { int num = bsBuff >> 24; try { bsStream.WriteByte((byte)num); } catch (IOException ex) { throw ex; } bsBuff <<= 8; bsLive -= 8; bytesOut++; } } private void BsW(int n, int v) { while (bsLive >= 8) { int num = bsBuff >> 24; try { bsStream.WriteByte((byte)num); } catch (IOException ex) { throw ex; } bsBuff <<= 8; bsLive -= 8; bytesOut++; } bsBuff |= v << 32 - bsLive - n; bsLive += n; } private void BsPutUChar(int c) { BsW(8, c); } private void BsPutint(int u) { BsW(8, (u >> 24) & 0xFF); BsW(8, (u >> 16) & 0xFF); BsW(8, (u >> 8) & 0xFF); BsW(8, u & 0xFF); } private void BsPutIntVS(int numBits, int c) { BsW(numBits, c); } private void SendMTFValues() { char[][] array = CBZip2InputStream.InitCharArray(6, 258); int num = 0; int num2 = nInUse + 2; for (int i = 0; i < 6; i++) { for (int j = 0; j < num2; j++) { array[i][j] = '\u000f'; } } if (nMTF <= 0) { Panic(); } int num3 = ((nMTF < 200) ? 2 : ((nMTF < 600) ? 3 : ((nMTF < 1200) ? 4 : ((nMTF >= 2400) ? 6 : 5)))); int num4 = num3; int num5 = nMTF; int num6 = 0; while (num4 > 0) { int num7 = num5 / num4; int num8 = num6 - 1; int k; for (k = 0; k < num7; k += mtfFreq[num8]) { if (num8 >= num2 - 1) { break; } num8++; } if (num8 > num6 && num4 != num3 && num4 != 1 && (num3 - num4) % 2 == 1) { k -= mtfFreq[num8]; num8--; } for (int j = 0; j < num2; j++) { if (j >= num6 && j <= num8) { array[num4 - 1][j] = '\0'; } else { array[num4 - 1][j] = '\u000f'; } } num4--; num6 = num8 + 1; num5 -= k; } int[][] array2 = CBZip2InputStream.InitIntArray(6, 258); int[] array3 = new int[6]; short[] array4 = new short[6]; for (int l = 0; l < 4; l++) { for (int i = 0; i < num3; i++) { array3[i] = 0; } for (int i = 0; i < num3; i++) { for (int j = 0; j < num2; j++) { array2[i][j] = 0; } } num = 0; int num9 = 0; num6 = 0; while (num6 < nMTF) { int num8 = num6 + 50 - 1; if (num8 >= nMTF) { num8 = nMTF - 1; } for (int i = 0; i < num3; i++) { array4[i] = 0; } nint num19; if (num3 == 6) { short num11; short num12; short num13; short num14; short num15; short num10 = (num11 = (num12 = (num13 = (num14 = (num15 = 0))))); for (int m = num6; m <= num8; m++) { short num16 = szptr[m]; num10 += (short)array[0][num16]; num11 += (short)array[1][num16]; num12 += (short)array[2][num16]; num13 += (short)array[3][num16]; num14 += (short)array[4][num16]; num15 += (short)array[5][num16]; } array4[0] = num10; array4[1] = num11; array4[2] = num12; array4[3] = num13; array4[4] = num14; array4[5] = num15; } else { for (int m = num6; m <= num8; m++) { short num17 = szptr[m]; for (int i = 0; i < num3; i++) { short[] array6; short[] array5 = (array6 = array4); int num18 = i; num19 = num18; array5[num18] = (short)(array6[num19] + (short)array[i][num17]); } } } int num20 = 999999999; int num21 = -1; for (int i = 0; i < num3; i++) { if (array4[i] < num20) { num20 = array4[i]; num21 = i; } } num9 += num20; int[] array8; int[] array7 = (array8 = array3); int num22 = num21; num19 = num22; array7[num22] = array8[num19] + 1; selector[num] = (char)num21; num++; for (int m = num6; m <= num8; m++) { int[] array9 = (array8 = array2[num21]); short num23 = szptr[m]; num19 = num23; array9[num23] = array8[num19] + 1; } num6 = num8 + 1; } for (int i = 0; i < num3; i++) { HbMakeCodeLengths(array[i], array2[i], num2, 20); } } array2 = null; array3 = null; array4 = null; if (num3 >= 8) { Panic(); } if (num >= 32768 || num > 18002) { Panic(); } char[] array10 = new char[6]; for (int m = 0; m < num3; m++) { array10[m] = (char)m; } for (int m = 0; m < num; m++) { char c = selector[m]; int num24 = 0; char c2 = array10[num24]; while (c != c2) { num24++; char c3 = c2; c2 = array10[num24]; array10[num24] = c3; } array10[0] = c2; selectorMtf[m] = (char)num24; } int[][] array11 = CBZip2InputStream.InitIntArray(6, 258); for (int i = 0; i < num3; i++) { int num25 = 32; int num26 = 0; for (int m = 0; m < num2; m++) { if (array[i][m] > num26) { num26 = array[i][m]; } if (array[i][m] < num25) { num25 = array[i][m]; } } if (num26 > 20) { Panic(); } if (num25 < 1) { Panic(); } HbAssignCodes(array11[i], array[i], num25, num26, num2); } bool[] array12 = new bool[16]; for (int m = 0; m < 16; m++) { array12[m] = false; for (int num24 = 0; num24 < 16; num24++) { if (inUse[m * 16 + num24]) { array12[m] = true; } } } for (int m = 0; m < 16; m++) { if (array12[m]) { BsW(1, 1); } else { BsW(1, 0); } } for (int m = 0; m < 16; m++) { if (!array12[m]) { continue; } for (int num24 = 0; num24 < 16; num24++) { if (inUse[m * 16 + num24]) { BsW(1, 1); } else { BsW(1, 0); } } } BsW(3, num3); BsW(15, num); for (int m = 0; m < num; m++) { for (int num24 = 0; num24 < selectorMtf[m]; num24++) { BsW(1, 1); } BsW(1, 0); } for (int i = 0; i < num3; i++) { int n = array[i][0]; BsW(5, n); for (int m = 0; m < num2; m++) { for (; n < array[i][m]; n++) { BsW(2, 2); } while (n > array[i][m]) { BsW(2, 3); n--; } BsW(1, 0); } } int num27 = 0; num6 = 0; while (num6 < nMTF) { int num8 = num6 + 50 - 1; if (num8 >= nMTF) { num8 = nMTF - 1; } for (int m = num6; m <= num8; m++) { BsW(array[(uint)selector[num27]][szptr[m]], array11[(uint)selector[num27]][szptr[m]]); } num6 = num8 + 1; num27++; } if (num27 != num) { Panic(); } } private void MoveToFrontCodeAndSend() { BsPutIntVS(24, origPtr); GenerateMTFValues(); SendMTFValues(); } private void SimpleSort(int lo, int hi, int d) { int num = hi - lo + 1; if (num < 2) { return; } int i; for (i = 0; incs[i] < num; i++) { } for (i--; i >= 0; i--) { int num2 = incs[i]; int num3 = lo + num2; while (num3 <= hi) { int num4 = zptr[num3]; int num5 = num3; while (FullGtU(zptr[num5 - num2] + d, num4 + d)) { zptr[num5] = zptr[num5 - num2]; num5 -= num2; if (num5 <= lo + num2 - 1) { break; } } zptr[num5] = num4; num3++; if (num3 > hi) { break; } num4 = zptr[num3]; num5 = num3; while (FullGtU(zptr[num5 - num2] + d, num4 + d)) { zptr[num5] = zptr[num5 - num2]; num5 -= num2; if (num5 <= lo + num2 - 1) { break; } } zptr[num5] = num4; num3++; if (num3 > hi) { break; } num4 = zptr[num3]; num5 = num3; while (FullGtU(zptr[num5 - num2] + d, num4 + d)) { zptr[num5] = zptr[num5 - num2]; num5 -= num2; if (num5 <= lo + num2 - 1) { break; } } zptr[num5] = num4; num3++; if (workDone > workLimit && firstAttempt) { return; } } } } private void Vswap(int p1, int p2, int n) { int num = 0; while (n > 0) { num = zptr[p1]; zptr[p1] = zptr[p2]; zptr[p2] = num; p1++; p2++; n--; } } private char Med3(char a, char b, char c) { if (a > b) { char c2 = a; a = b; b = c2; } if (b > c) { char c2 = b; b = c; c = c2; } if (a > b) { b = a; } return b; } private void QSort3(int loSt, int hiSt, int dSt) { StackElem[] array = new StackElem[1000]; for (int i = 0; i < 1000; i++) { array[i] = new StackElem(); } int num = 0; array[num].ll = loSt; array[num].hh = hiSt; array[num].dd = dSt; num++; while (num > 0) { if (num >= 1000) { Panic(); } num--; int ll = array[num].ll; int hh = array[num].hh; int dd = array[num].dd; if (hh - ll < 20 || dd > 10) { SimpleSort(ll, hh, dd); if (workDone > workLimit && firstAttempt) { break; } continue; } int num2 = Med3(block[zptr[ll] + dd + 1], block[zptr[hh] + dd + 1], block[zptr[ll + hh >> 1] + dd + 1]); int num4; int num3 = (num4 = ll); int num6; int num5 = (num6 = hh); int num7; while (true) { if (num3 <= num5) { num7 = block[zptr[num3] + dd + 1] - num2; if (num7 == 0) { int num8 = 0; num8 = zptr[num3]; zptr[num3] = zptr[num4]; zptr[num4] = num8; num4++; num3++; continue; } if (num7 <= 0) { num3++; continue; } } while (num3 <= num5) { num7 = block[zptr[num5] + dd + 1] - num2; if (num7 == 0) { int num9 = 0; num9 = zptr[num5]; zptr[num5] = zptr[num6]; zptr[num6] = num9; num6--; num5--; } else { if (num7 < 0) { break; } num5--; } } if (num3 > num5) { break; } int num10 = zptr[num3]; zptr[num3] = zptr[num5]; zptr[num5] = num10; num3++; num5--; } if (num6 < num4) { array[num].ll = ll; array[num].hh = hh; array[num].dd = dd + 1; num++; continue; } num7 = ((num4 - ll < num3 - num4) ? (num4 - ll) : (num3 - num4)); Vswap(ll, num3 - num7, num7); int num11 = ((hh - num6 < num6 - num5) ? (hh - num6) : (num6 - num5)); Vswap(num3, hh - num11 + 1, num11); num7 = ll + num3 - num4 - 1; num11 = hh - (num6 - num5) + 1; array[num].ll = ll; array[num].hh = num7; array[num].dd = dd; num++; array[num].ll = num7 + 1; array[num].hh = num11 - 1; array[num].dd = dd + 1; num++; array[num].ll = num11; array[num].hh = hh; array[num].dd = dd; num++; } } private void MainSort() { int[] array = new int[256]; int[] array2 = new int[256]; bool[] array3 = new bool[256]; for (int i = 0; i < 20; i++) { block[last + i + 2] = block[i % (last + 1) + 1]; } for (int i = 0; i <= last + 20; i++) { quadrant[i] = 0; } block[0] = block[last + 1]; if (last < 4000) { for (int i = 0; i <= last; i++) { zptr[i] = i; } firstAttempt = false; workDone = (workLimit = 0); SimpleSort(0, last, 0); return; } int num = 0; for (int i = 0; i <= 255; i++) { array3[i] = false; } for (int i = 0; i <= 65536; i++) { ftab[i] = 0; } int num2 = block[0]; int[] array5; nint num5; for (int i = 0; i <= last; i++) { int num3 = block[i + 1]; int[] array4 = (array5 = ftab); int num4 = (num2 << 8) + num3; num5 = num4; array4[num4] = array5[num5] + 1; num2 = num3; } for (int i = 1; i <= 65536; i++) { int[] array6 = (array5 = ftab); int num6 = i; num5 = num6; array6[num6] = array5[num5] + ftab[i - 1]; } num2 = block[1]; int num7; for (int i = 0; i < last; i++) { int num3 = block[i + 2]; num7 = (num2 << 8) + num3; num2 = num3; int[] array7 = (array5 = ftab); int num8 = num7; num5 = num8; array7[num8] = array5[num5] - 1; zptr[ftab[num7]] = i; } num7 = (int)(((uint)block[last + 1] << 8) + block[1]); int[] array8 = (array5 = ftab); int num9 = num7; num5 = num9; array8[num9] = array5[num5] - 1; zptr[ftab[num7]] = last; for (int i = 0; i <= 255; i++) { array[i] = i; } int num10 = 1; do { num10 = 3 * num10 + 1; } while (num10 <= 256); do { num10 /= 3; for (int i = num10; i <= 255; i++) { int num11 = array[i]; num7 = i; while (ftab[array[num7 - num10] + 1 << 8] - ftab[array[num7 - num10] << 8] > ftab[num11 + 1 << 8] - ftab[num11 << 8]) { array[num7] = array[num7 - num10]; num7 -= num10; if (num7 <= num10 - 1) { break; } } array[num7] = num11; } } while (num10 != 1); for (int i = 0; i <= 255; i++) { int num12 = array[i]; for (num7 = 0; num7 <= 255; num7++) { int num13 = (num12 << 8) + num7; if ((ftab[num13] & 0x200000) == 2097152) { continue; } int num14 = ftab[num13] & -2097153; int num15 = (ftab[num13 + 1] & -2097153) - 1; if (num15 > num14) { QSort3(num14, num15, 2); num += num15 - num14 + 1; if (workDone > workLimit && firstAttempt) { return; } } int[] array9 = (array5 = ftab); num5 = num13; array9[num13] = array5[num5] | 0x200000; } array3[num12] = true; if (i < 255) { int num16 = ftab[num12 << 8] & -2097153; int num17 = (ftab[num12 + 1 << 8] & -2097153) - num16; int j; for (j = 0; num17 >> j > 65534; j++) { } for (num7 = 0; num7 < num17; num7++) { int num18 = zptr[num16 + num7]; int num19 = num7 >> j; quadrant[num18] = num19; if (num18 < 20) { quadrant[num18 + last + 1] = num19; } } if (num17 - 1 >> j > 65535) { Panic(); } } for (num7 = 0; num7 <= 255; num7++) { array2[num7] = ftab[(num7 << 8) + num12] & -2097153; } for (num7 = ftab[num12 << 8] & -2097153; num7 < (ftab[num12 + 1 << 8] & -2097153); num7++) { num2 = block[zptr[num7]]; if (!array3[num2]) { zptr[array2[num2]] = ((zptr[num7] == 0) ? last : (zptr[num7] - 1)); int[] array10 = (array5 = array2); int num20 = num2; num5 = num20; array10[num20] = array5[num5] + 1; } } for (num7 = 0; num7 <= 255; num7++) { int[] array11 = (array5 = ftab); int num21 = (num7 << 8) + num12; num5 = num21; array11[num21] = array5[num5] | 0x200000; } } } private void RandomiseBlock() { int num = 0; int num2 = 0; for (int i = 0; i < 256; i++) { inUse[i] = false; } for (int i = 0; i <= last; i++) { if (num == 0) { num = (ushort)BZip2Constants.rNums[num2]; num2++; if (num2 == 512) { num2 = 0; } } num--; char[] array2; char[] array = (array2 = block); int num3 = i + 1; nint num4 = num3; array[num3] = (char)((uint)array2[num4] ^ ((num == 1) ? 1u : 0u)); char[] array3 = (array2 = block); int num5 = i + 1; num4 = num5; array3[num5] = (char)(array2[num4] & 0xFF); inUse[(uint)block[i + 1]] = true; } } private void DoReversibleTransformation() { workLimit = workFactor * last; workDone = 0; blockRandomised = false; firstAttempt = true; MainSort(); if (workDone > workLimit && firstAttempt) { RandomiseBlock(); workLimit = (workDone = 0); blockRandomised = true; firstAttempt = false; MainSort(); } origPtr = -1; for (int i = 0; i <= last; i++) { if (zptr[i] == 0) { origPtr = i; break; } } if (origPtr == -1) { Panic(); } } private bool FullGtU(int i1, int i2) { char c = block[i1 + 1]; char c2 = block[i2 + 1]; if (c != c2) { return c > c2; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } i1++; i2++; int num = last + 1; do { c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } int num2 = quadrant[i1]; int num3 = quadrant[i2]; if (num2 != num3) { return num2 > num3; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } num2 = quadrant[i1]; num3 = quadrant[i2]; if (num2 != num3) { return num2 > num3; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } num2 = quadrant[i1]; num3 = quadrant[i2]; if (num2 != num3) { return num2 > num3; } i1++; i2++; c = block[i1 + 1]; c2 = block[i2 + 1]; if (c != c2) { return c > c2; } num2 = quadrant[i1]; num3 = quadrant[i2]; if (num2 != num3) { return num2 > num3; } i1++; i2++; if (i1 > last) { i1 -= last; i1--; } if (i2 > last) { i2 -= last; i2--; } num -= 4; workDone++; } while (num >= 0); return false; } private void AllocateCompressStructures() { int num = 100000 * blockSize100k; block = new char[num + 1 + 20]; quadrant = new int[num + 20]; zptr = new int[num]; ftab = new int[65537]; if (block != null && quadrant != null && zptr != null) { _ = ftab; } szptr = new short[2 * num]; } private void GenerateMTFValues() { char[] array = new char[256]; MakeMaps(); int num = nInUse + 1; for (int i = 0; i <= num; i++) { mtfFreq[i] = 0; } int num2 = 0; int num3 = 0; for (int i = 0; i < nInUse; i++) { array[i] = (char)i; } int[] array2; nint num6; for (int i = 0; i <= last; i++) { char c = unseqToSeq[(uint)block[zptr[i]]]; int num4 = 0; char c2 = array[num4]; while (c != c2) { num4++; char c3 = c2; c2 = array[num4]; array[num4] = c3; } array[0] = c2; if (num4 == 0) { num3++; continue; } if (num3 > 0) { num3--; while (true) { switch (num3 % 2) { case 0: szptr[num2] = 0; num2++; (array2 = mtfFreq)[0] = array2[0] + 1; break; case 1: szptr[num2] = 1; num2++; (array2 = mtfFreq)[1] = array2[1] + 1; break; } if (num3 < 2) { break; } num3 = (num3 - 2) / 2; } num3 = 0; } szptr[num2] = (short)(num4 + 1); num2++; int[] array3 = (array2 = mtfFreq); int num5 = num4 + 1; num6 = num5; array3[num5] = array2[num6] + 1; } if (num3 > 0) { num3--; while (true) { switch (num3 % 2) { case 0: szptr[num2] = 0; num2++; (array2 = mtfFreq)[0] = array2[0] + 1; break; case 1: szptr[num2] = 1; num2++; (array2 = mtfFreq)[1] = array2[1] + 1; break; } if (num3 < 2) { break; } num3 = (num3 - 2) / 2; } } szptr[num2] = (short)num; num2++; int[] array4 = (array2 = mtfFreq); num6 = num; array4[num] = array2[num6] + 1; nMTF = num2; } public override int Read(byte[] buffer, int offset, int count) { return 0; } public override long Seek(long offset, SeekOrigin origin) { return 0L; } public override void SetLength(long value) { } public override void Write(byte[] buffer, int offset, int count) { for (int i = 0; i < count; i++) { WriteByte(buffer[i + offset]); } } }