Files
BinaryObjectScanner/BinaryObjectScanner.Compression/bzip2/decompress.cs
Matt Nadareski 473cbc5694 BOS.* -> BOS.*
2023-03-07 16:59:14 -05:00

2194 lines
82 KiB
C#

using System.Runtime.InteropServices;
using static BinaryObjectScanner.Compression.bzip2.Constants;
using static BinaryObjectScanner.Compression.bzip2.Huffman;
namespace BinaryObjectScanner.Compression.bzip2
{
/// <see href="https://github.com/ladislav-zezula/StormLib/blob/master/src/bzip2/decompress.c"/>
internal static unsafe class decompress
{
private static void makeMaps_d(DState s)
{
int i;
s.nInUse = 0;
for (i = 0; i < 256; i++)
{
if (s.inUse[i])
{
s.seqToUnseq[s.nInUse] = (byte)i;
s.nInUse++;
}
}
}
public static int BZ2_decompress(DState s)
{
byte uc = 0;
int retVal;
int minLen, maxLen;
bz_stream strm = s.strm;
/* stuff that needs to be saved/restored */
int i;
int j;
int t;
int alphaSize;
int nGroups;
int nSelectors;
int EOB;
int groupNo;
int groupPos;
int nextSym;
int nblockMAX;
int nblock;
int es;
int N;
int curr;
int zt;
int zn;
int zvec;
int zj;
int gSel;
int gMinlen;
int* gLimit;
int* gBase;
int* gPerm;
if (s.state == BZ_X_MAGIC_1)
{
/*initialise the save area*/
s.save_i = 0;
s.save_j = 0;
s.save_t = 0;
s.save_alphaSize = 0;
s.save_nGroups = 0;
s.save_nSelectors = 0;
s.save_EOB = 0;
s.save_groupNo = 0;
s.save_groupPos = 0;
s.save_nextSym = 0;
s.save_nblockMAX = 0;
s.save_nblock = 0;
s.save_es = 0;
s.save_N = 0;
s.save_curr = 0;
s.save_zt = 0;
s.save_zn = 0;
s.save_zvec = 0;
s.save_zj = 0;
s.save_gSel = 0;
s.save_gMinlen = 0;
s.save_gLimit = null;
s.save_gBase = null;
s.save_gPerm = null;
}
/*restore from the save area*/
i = s.save_i;
j = s.save_j;
t = s.save_t;
alphaSize = s.save_alphaSize;
nGroups = s.save_nGroups;
nSelectors = s.save_nSelectors;
EOB = s.save_EOB;
groupNo = s.save_groupNo;
groupPos = s.save_groupPos;
nextSym = s.save_nextSym;
nblockMAX = s.save_nblockMAX;
nblock = s.save_nblock;
es = s.save_es;
N = s.save_N;
curr = s.save_curr;
zt = s.save_zt;
zn = s.save_zn;
zvec = s.save_zvec;
zj = s.save_zj;
gSel = s.save_gSel;
gMinlen = s.save_gMinlen;
gLimit = s.save_gLimit;
gBase = s.save_gBase;
gPerm = s.save_gPerm;
retVal = BZ_OK;
switch (s.state)
{
// States that don't map to cases -- TODO: Figure out how to reference the right labels
// case BZ_X_MAPPING_1: goto BZ_X_MAPPING_1; break;
// case BZ_X_MAPPING_2: goto BZ_X_MAPPING_2; break;
// case BZ_X_SELECTOR_3: goto BZ_X_SELECTOR_3; break;
// case BZ_X_CODING_1: goto BZ_X_CODING_1; break;
// case BZ_X_CODING_2: goto BZ_X_CODING_2; break;
// case BZ_X_CODING_3: goto BZ_X_CODING_3; break;
// case BZ_X_MTF_2: goto BZ_X_MTF_2; break;
// case BZ_X_MTF_3: goto BZ_X_MTF_3; break;
// case BZ_X_MTF_4: goto BZ_X_MTF_4; break;
// case BZ_X_MTF_5: goto BZ_X_MTF_5; break;
// case BZ_X_MTF_6: goto BZ_X_MTF_6; break;
case BZ_X_MAGIC_1:
s.state = BZ_X_MAGIC_1;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != BZ_HDR_B)
{
retVal = BZ_DATA_ERROR_MAGIC;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_MAGIC_2;
case BZ_X_MAGIC_2:
s.state = BZ_X_MAGIC_2;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != BZ_HDR_Z)
{
retVal = BZ_DATA_ERROR_MAGIC;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_MAGIC_3;
case BZ_X_MAGIC_3:
s.state = BZ_X_MAGIC_3;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != BZ_HDR_h)
{
retVal = BZ_DATA_ERROR_MAGIC;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_MAGIC_4;
case BZ_X_MAGIC_4:
s.state = BZ_X_MAGIC_4;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
s.blockSize100k = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (s.blockSize100k < (BZ_HDR_0 + 1) || s.blockSize100k > (BZ_HDR_0 + 9))
{
retVal = BZ_DATA_ERROR_MAGIC;
goto save_state_and_return;
}
s.blockSize100k -= BZ_HDR_0;
if (s.smallDecompress)
{
s.ll16 = (ushort*)Marshal.AllocHGlobal(s.blockSize100k * 100000 * sizeof(ushort));
s.ll4 = (byte*)Marshal.AllocHGlobal(((1 + s.blockSize100k * 100000) >> 1) * sizeof(byte));
if (s.ll16 == null || s.ll4 == null)
{
retVal = BZ_MEM_ERROR;
goto save_state_and_return;
}
}
else
{
s.tt = (uint*)Marshal.AllocHGlobal(s.blockSize100k * 100000 * sizeof(int));
if (s.tt == null)
{
retVal = BZ_MEM_ERROR;
goto save_state_and_return;
}
}
// Fallthrough
goto case BZ_X_BLKHDR_1;
case BZ_X_BLKHDR_1:
s.state = BZ_X_BLKHDR_1;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc == 0x17)
goto case BZ_X_ENDHDR_2;
if (uc != 0x31)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_BLKHDR_2;
case BZ_X_BLKHDR_2:
s.state = BZ_X_BLKHDR_2;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x41)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_BLKHDR_3;
case BZ_X_BLKHDR_3:
s.state = BZ_X_BLKHDR_3;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x59)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_BLKHDR_4;
case BZ_X_BLKHDR_4:
s.state = BZ_X_BLKHDR_4;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x26)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_BLKHDR_5;
case BZ_X_BLKHDR_5:
s.state = BZ_X_BLKHDR_5;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x53)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_BLKHDR_6;
case BZ_X_BLKHDR_6:
s.state = BZ_X_BLKHDR_6;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x59)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
s.currBlockNo++;
// if (s.verbosity >= 2)
// VPrintf1("\n [%d: huff+mtf ", s.currBlockNo);
s.storedBlockCRC = 0;
// Fallthrough
goto case BZ_X_BCRC_1;
case BZ_X_BCRC_1:
s.state = BZ_X_BCRC_1;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedBlockCRC = (s.storedBlockCRC << 8) | ((uint)uc);
// Fallthrough
goto case BZ_X_BCRC_2;
case BZ_X_BCRC_2:
s.state = BZ_X_BCRC_2;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedBlockCRC = (s.storedBlockCRC << 8) | ((uint)uc);
// Fallthrough
goto case BZ_X_BCRC_3;
case BZ_X_BCRC_3:
s.state = BZ_X_BCRC_3;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedBlockCRC = (s.storedBlockCRC << 8) | ((uint)uc);
// Fallthrough
goto case BZ_X_BCRC_4;
case BZ_X_BCRC_4:
s.state = BZ_X_BCRC_4;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedBlockCRC = (s.storedBlockCRC << 8) | ((uint)uc);
// Fallthrough
goto case BZ_X_RANDBIT;
case BZ_X_RANDBIT:
s.state = BZ_X_RANDBIT;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
s.blockRandomised = v != 0;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.origPtr = 0;
// Fallthrough
goto case BZ_X_ORIGPTR_1;
case BZ_X_ORIGPTR_1:
s.state = BZ_X_ORIGPTR_1;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.origPtr = (s.origPtr << 8) | ((int)uc);
// Fallthrough
goto case BZ_X_ORIGPTR_2;
case BZ_X_ORIGPTR_2:
s.state = BZ_X_ORIGPTR_2;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.origPtr = (s.origPtr << 8) | ((int)uc);
// Fallthrough
goto case BZ_X_ORIGPTR_3;
case BZ_X_ORIGPTR_3:
s.state = BZ_X_ORIGPTR_3;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.origPtr = (s.origPtr << 8) | ((int)uc);
if (s.origPtr < 0)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
if (s.origPtr > 10 + 100000 * s.blockSize100k)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
/*--- Receive the mapping table ---*/
for (i = 0; i < 16; i++)
{
BZ_X_MAPPING_1:
s.state = BZ_X_MAPPING_1;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc == 1)
s.inUse16[i] = true;
else
s.inUse16[i] = false;
}
for (i = 0; i < 256; i++)
{
s.inUse[i] = false;
}
for (i = 0; i < 16; i++)
{
if (s.inUse16[i])
{
for (j = 0; j < 16; j++)
{
BZ_X_MAPPING_2:
s.state = BZ_X_MAPPING_2;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc == 1)
s.inUse[i * 16 + j] = true;
}
}
}
makeMaps_d(s);
if (s.nInUse == 0)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
alphaSize = s.nInUse + 2;
// Fallthrough
goto case BZ_X_SELECTOR_1;
/*--- Now the selectors ---*/
case BZ_X_SELECTOR_1:
s.state = BZ_X_SELECTOR_1;
while (true)
{
if (s.bsLive >= 3)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 3)) & ((1 << 3) - 1));
s.bsLive -= 3;
nGroups = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (nGroups < 2 || nGroups > 6)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_SELECTOR_2;
case BZ_X_SELECTOR_2:
s.state = BZ_X_SELECTOR_2;
while (true)
{
if (s.bsLive >= 15)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 15)) & ((1 << 15) - 1));
s.bsLive -= 15;
nSelectors = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (nSelectors < 1)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
for (i = 0; i < nSelectors; i++)
{
j = 0;
while (true)
{
BZ_X_SELECTOR_3:
s.state = BZ_X_SELECTOR_3;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)s.strm.next_in;
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc == 0)
break;
j++;
if (j >= nGroups)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
}
s.selectorMtf[i] = (byte)j;
}
/*--- Undo the MTF values for the selectors. ---*/
{
byte[] pos = new byte[BZ_N_GROUPS]; byte tmp, v;
for (v = 0; v < nGroups; v++)
{
pos[v] = v;
}
for (i = 0; i < nSelectors; i++)
{
v = s.selectorMtf[i];
tmp = pos[v];
while (v > 0) { pos[v] = pos[v - 1]; v--; }
pos[0] = tmp;
s.selector[i] = tmp;
}
}
/*--- Now the coding tables ---*/
for (t = 0; t < nGroups; t++)
{
BZ_X_CODING_1:
s.state = BZ_X_CODING_1;
while (true)
{
if (s.bsLive >= 5)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 5)) & ((1 << 5) - 1));
s.bsLive -= 5;
curr = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
for (i = 0; i < alphaSize; i++)
{
while (true)
{
if (curr < 1 || curr > 20)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
BZ_X_CODING_2:
s.state = BZ_X_CODING_2;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc == 0)
break;
BZ_X_CODING_3:
s.state = BZ_X_CODING_3;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc == 0)
curr++;
else
curr--;
}
s.len[t, i] = (byte)curr;
}
}
/*--- Create the Huffman decoding tables ---*/
for (t = 0; t < nGroups; t++)
{
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++)
{
if (s.len[t, i] > maxLen)
maxLen = s.len[t, i];
if (s.len[t, i] < minLen)
minLen = s.len[t, i];
}
fixed (int* s_limit_t_0 = &s.limit[t, 0])
fixed (int* s_base_t_0 = &s.@base[t, 0])
fixed (int* s_perm_t_0 = &s.perm[t, 0])
fixed (byte* s_len_t_0 = &s.len[t, 0])
{
BZ2_hbCreateDecodeTables(s_limit_t_0, s_base_t_0, s_perm_t_0, s_len_t_0, minLen, maxLen, alphaSize);
}
s.minLens[t] = minLen;
}
/*--- Now the MTF values ---*/
EOB = s.nInUse + 1;
nblockMAX = 100000 * s.blockSize100k;
groupNo = -1;
groupPos = 0;
for (i = 0; i <= 255; i++) s.unzftab[i] = 0;
/*-- MTF init --*/
{
int ii, jj, kk;
kk = MTFA_SIZE - 1;
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--)
{
for (jj = MTFL_SIZE - 1; jj >= 0; jj--)
{
s.mtfa[kk] = (byte)(ii * MTFL_SIZE + jj);
kk--;
}
s.mtfbase[ii] = kk + 1;
}
}
/*-- end MTF init --*/
nblock = 0;
if (groupPos == 0)
{
groupNo++;
if (groupNo >= nSelectors)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
groupPos = BZ_G_SIZE;
gSel = s.selector[groupNo];
gMinlen = s.minLens[gSel];
fixed (int* s_limit_gSel_0 = &s.limit[gSel, 0])
gLimit = s_limit_gSel_0;
fixed (int* s_perm_gSel_0 = &s.perm[gSel, 0])
gPerm = s_perm_gSel_0;
fixed (int* s_base_gSel_0 = &s.@base[gSel, 0])
gPerm = s_base_gSel_0;
}
groupPos--;
zn = gMinlen;
// Fallthrough
goto case BZ_X_MTF_1;
case BZ_X_MTF_1:
s.state = BZ_X_MTF_1;
while (true)
{
if (s.bsLive >= zn)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - zn)) & ((1 << zn) - 1));
s.bsLive -= zn;
zvec = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
while (true)
{
if (zn > 20 /* the longest code */)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
if (zvec <= gLimit[zn])
break;
zn++;
BZ_X_MTF_2:
s.state = BZ_X_MTF_2;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
zj = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
zvec = (zvec << 1) | zj;
};
if (zvec - gBase[zn] < 0 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
nextSym = gPerm[zvec - gBase[zn]];
while (true)
{
if (nextSym == EOB) break;
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB)
{
es = -1;
N = 1;
do
{
if (nextSym == BZ_RUNA)
es = es + (0 + 1) * N;
else if (nextSym == BZ_RUNB)
es = es + (1 + 1) * N;
N = N * 2;
if (groupPos == 0)
{
groupNo++;
if (groupNo >= nSelectors)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
groupPos = BZ_G_SIZE;
gSel = s.selector[groupNo];
gMinlen = s.minLens[gSel];
fixed (int* s_limit_gSel_0 = &s.limit[gSel, 0])
gLimit = s_limit_gSel_0;
fixed (int* s_perm_gSel_0 = &s.perm[gSel, 0])
gPerm = s_perm_gSel_0;
fixed (int* s_base_gSel_0 = &s.@base[gSel, 0])
gPerm = s_base_gSel_0;
}
groupPos--;
zn = gMinlen;
BZ_X_MTF_3:
s.state = BZ_X_MTF_3;
while (true)
{
if (s.bsLive >= zn)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - zn)) & ((1 << zn) - 1));
s.bsLive -= zn;
zvec = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
while (true)
{
if (zn > 20 /* the longest code */)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
if (zvec <= gLimit[zn])
break;
zn++;
BZ_X_MTF_4:
s.state = BZ_X_MTF_4;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
zj = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
zvec = (zvec << 1) | zj;
};
if (zvec - gBase[zn] < 0 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
nextSym = gPerm[zvec - gBase[zn]];
} while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
es++;
uc = s.seqToUnseq[s.mtfa[s.mtfbase[0]]];
s.unzftab[uc] += es;
if (s.smallDecompress)
{
while (es > 0)
{
if (nblock >= nblockMAX)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
s.ll16[nblock] = (ushort)uc;
nblock++;
es--;
}
}
else
{
while (es > 0)
{
if (nblock >= nblockMAX)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
s.tt[nblock] = (uint)uc;
nblock++;
es--;
}
};
continue;
}
else
{
if (nblock >= nblockMAX)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
/*-- uc = MTF ( nextSym-1 ) --*/
{
int ii, jj, kk, pp, lno, off;
uint nn;
nn = (uint)(nextSym - 1);
if (nn < MTFL_SIZE)
{
/* avoid general-case expense */
pp = s.mtfbase[0];
uc = s.mtfa[pp + nn];
while (nn > 3)
{
int z = (int)(pp + nn);
s.mtfa[(z)] = s.mtfa[(z) - 1];
s.mtfa[(z) - 1] = s.mtfa[(z) - 2];
s.mtfa[(z) - 2] = s.mtfa[(z) - 3];
s.mtfa[(z) - 3] = s.mtfa[(z) - 4];
nn -= 4;
}
while (nn > 0)
{
s.mtfa[(pp + nn)] = s.mtfa[(pp + nn) - 1]; nn--;
};
s.mtfa[pp] = uc;
}
else
{
/* general case */
lno = (int)(nn / MTFL_SIZE);
off = (int)(nn % MTFL_SIZE);
pp = s.mtfbase[lno] + off;
uc = s.mtfa[pp];
while (pp > s.mtfbase[lno])
{
s.mtfa[pp] = s.mtfa[pp - 1]; pp--;
};
s.mtfbase[lno]++;
while (lno > 0)
{
s.mtfbase[lno]--;
s.mtfa[s.mtfbase[lno]] = s.mtfa[s.mtfbase[lno - 1] + MTFL_SIZE - 1];
lno--;
}
s.mtfbase[0]--;
s.mtfa[s.mtfbase[0]] = uc;
if (s.mtfbase[0] == 0)
{
kk = MTFA_SIZE - 1;
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--)
{
for (jj = MTFL_SIZE - 1; jj >= 0; jj--)
{
s.mtfa[kk] = s.mtfa[s.mtfbase[ii] + jj];
kk--;
}
s.mtfbase[ii] = kk + 1;
}
}
}
}
/*-- end uc = MTF ( nextSym-1 ) --*/
s.unzftab[s.seqToUnseq[uc]]++;
if (s.smallDecompress)
s.ll16[nblock] = (ushort)(s.seqToUnseq[uc]);
else
s.tt[nblock] = (uint)(s.seqToUnseq[uc]);
nblock++;
if (groupPos == 0)
{
groupNo++;
if (groupNo >= nSelectors)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
groupPos = BZ_G_SIZE;
gSel = s.selector[groupNo];
gMinlen = s.minLens[gSel];
fixed (int* s_limit_gSel_0 = &s.limit[gSel, 0])
gLimit = s_limit_gSel_0;
fixed (int* s_perm_gSel_0 = &s.perm[gSel, 0])
gPerm = s_perm_gSel_0;
fixed (int* s_base_gSel_0 = &s.@base[gSel, 0])
gPerm = s_base_gSel_0;
}
groupPos--;
zn = gMinlen;
BZ_X_MTF_5:
s.state = BZ_X_MTF_5;
while (true)
{
if (s.bsLive >= zn)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - zn)) & ((1 << zn) - 1));
s.bsLive -= zn;
zvec = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
while (true)
{
if (zn > 20 /* the longest code */)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
if (zvec <= gLimit[zn])
break;
zn++;
BZ_X_MTF_6:
s.state = BZ_X_MTF_6;
while (true)
{
if (s.bsLive >= 1)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 1)) & ((1 << 1) - 1));
s.bsLive -= 1;
zj = (int)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
zvec = (zvec << 1) | zj;
};
if (zvec - gBase[zn] < 0 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
nextSym = gPerm[zvec - gBase[zn]];
}
continue;
}
/* Now we know what nblock is, we can do a better sanity
check on s.origPtr.
*/
if (s.origPtr < 0 || s.origPtr >= nblock)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
/*-- Set up cftab to facilitate generation of T^(-1) --*/
s.cftab[0] = 0;
for (i = 1; i <= 256; i++)
{
s.cftab[i] = s.unzftab[i - 1];
}
for (i = 1; i <= 256; i++)
{
s.cftab[i] += s.cftab[i - 1];
}
for (i = 0; i <= 256; i++)
{
if (s.cftab[i] < 0 || s.cftab[i] > nblock)
{
/* s.cftab[i] can legitimately be == nblock */
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
}
s.state_out_len = 0;
s.state_out_ch = 0;
s.calculatedBlockCRC = 0xffffffff;
s.state = BZ_X_OUTPUT;
// if (s.verbosity >= 2) VPrintf0("rt+rld");
if (s.smallDecompress)
{
/*-- Make a copy of cftab, used in generation of T --*/
for (i = 0; i <= 256; i++) s.cftabCopy[i] = s.cftab[i];
/*-- compute the T vector --*/
for (i = 0; i < nblock; i++)
{
uc = (byte)(s.ll16[i]);
s.ll16[i] = (ushort)(s.cftabCopy[uc] & 0x0000ffff);
if ((i & 0x1) == 0)
s.ll4[i >> 1] = (byte)((s.ll4[i >> 1] & 0xf0) | (s.cftabCopy[uc]));
else
s.ll4[i >> 1] = (byte)((s.ll4[i >> 1] & 0x0f) | ((s.cftabCopy[uc]) << 4));
s.cftabCopy[uc]++;
}
/*-- Compute T^(-1) by pointer reversal on T --*/
i = s.origPtr;
j = (int)(s.ll16[i] | (((((uint)s.ll4[i >> 1]) >> ((i << 2) & 0x4)) & 0xF) << 16));
do
{
int tmp = (int)(s.ll16[j] | (((((uint)s.ll4[j >> 1]) >> ((j << 2) & 0x4)) & 0xF) << 16));
s.ll16[j] = (ushort)(i & 0x0000ffff);
if ((j & 0x1) == 0)
s.ll4[j >> 1] = (byte)((s.ll4[j >> 1] & 0xf0) | i);
else
s.ll4[j >> 1] = (byte)((s.ll4[j >> 1] & 0x0f) | (i << 4));
i = j;
j = tmp;
}
while (i != s.origPtr);
s.tPos = (uint)s.origPtr;
s.nblock_used = 0;
if (s.blockRandomised)
{
s.rNToGo = 0;
s.rTPos = 0;
/* c_tPos is unsigned, hence test < 0 is pointless. */
if (s.tPos >= (uint)100000 * (uint)s.blockSize100k)
return 1;
fixed (int* s_cftab = s.cftab)
s.k0 = BZ2_indexIntoF((int)s.tPos, s_cftab);
s.tPos = (s.ll16[s.tPos]) | (((((uint)s.ll4[s.tPos >> 1]) >> (int)((s.tPos << 2) & 0x4)) & 0xF) << 16);
s.nblock_used++;
if (s.rNToGo == 0)
{
s.rNToGo = BZ2_rNums[s.rTPos];
s.rTPos++;
if (s.rTPos == 512)
s.rTPos = 0;
}
s.rNToGo--;
s.k0 ^= (s.rNToGo == 1) ? 1 : 0;
}
else
{
/* c_tPos is unsigned, hence test < 0 is pointless. */
if (s.tPos >= 100000 * (uint)s.blockSize100k)
return 1;
fixed (int* s_cftab = s.cftab)
s.k0 = BZ2_indexIntoF((int)s.tPos, s_cftab);
s.tPos = ((uint)s.ll16[s.tPos]) | (((((uint)s.ll4[s.tPos >> 1]) >> (int)((s.tPos << 2) & 0x4)) & 0xF) << 16);
s.nblock_used++;
}
}
else
{
/*-- compute the T^(-1) vector --*/
for (i = 0; i < nblock; i++)
{
uc = (byte)(s.tt[i] & 0xff);
s.tt[s.cftab[uc]] |= (uint)(i << 8);
s.cftab[uc]++;
}
s.tPos = s.tt[s.origPtr] >> 8;
s.nblock_used = 0;
if (s.blockRandomised)
{
s.rNToGo = 0;
s.rTPos = 0;
/* c_tPos is unsigned, hence test < 0 is pointless. */
if (s.tPos >= 100000 * (uint)s.blockSize100k)
return 1;
s.tPos = s.tt[s.tPos];
s.k0 = (byte)(s.tPos & 0xff);
s.tPos >>= 8;
s.nblock_used++;
if (s.rNToGo == 0)
{
s.rNToGo = BZ2_rNums[s.rTPos];
s.rTPos++;
if (s.rTPos == 512)
s.rTPos = 0;
}
s.rNToGo--;
s.k0 ^= (s.rNToGo == 1) ? 1 : 0;
}
else
{
/* c_tPos is unsigned, hence test < 0 is pointless. */
if (s.tPos >= 100000 * (uint)s.blockSize100k)
return 1;
s.tPos = s.tt[s.tPos];
s.k0 = (byte)(s.tPos & 0xff);
s.tPos >>= 8;
s.nblock_used++;
}
}
retVal = BZ_OK;
goto save_state_and_return;
case BZ_X_ENDHDR_2:
s.state = BZ_X_ENDHDR_2;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x72)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_ENDHDR_3;
case BZ_X_ENDHDR_3:
s.state = BZ_X_ENDHDR_3;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x45)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_ENDHDR_4;
case BZ_X_ENDHDR_4:
s.state = BZ_X_ENDHDR_4;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x38)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_ENDHDR_5;
case BZ_X_ENDHDR_5:
s.state = BZ_X_ENDHDR_5;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x50)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
// Fallthrough
goto case BZ_X_ENDHDR_6;
case BZ_X_ENDHDR_6:
s.state = BZ_X_ENDHDR_6;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
if (uc != 0x90)
{
retVal = BZ_DATA_ERROR;
goto save_state_and_return;
}
s.storedCombinedCRC = 0;
// Fallthrough
goto case BZ_X_CCRC_1;
case BZ_X_CCRC_1:
s.state = BZ_X_CCRC_1;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedCombinedCRC = (s.storedCombinedCRC << 8) | ((uint)uc);
// Fallthrough
goto case BZ_X_CCRC_2;
case BZ_X_CCRC_2:
s.state = BZ_X_CCRC_2;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedCombinedCRC = (s.storedCombinedCRC << 8) | ((uint)uc);
// Fallthrough
goto case BZ_X_CCRC_3;
case BZ_X_CCRC_3:
s.state = BZ_X_CCRC_3;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedCombinedCRC = (s.storedCombinedCRC << 8) | ((uint)uc);
// Fallthrough
goto case BZ_X_CCRC_4;
case BZ_X_CCRC_4:
s.state = BZ_X_CCRC_4;
while (true)
{
if (s.bsLive >= 8)
{
uint v;
v = (uint)((s.bsBuff >> (s.bsLive - 8)) & ((1 << 8) - 1));
s.bsLive -= 8;
uc = (byte)v;
break;
}
if (s.strm.avail_in == 0)
{
retVal = BZ_OK;
goto save_state_and_return;
}
s.bsBuff = (s.bsBuff << 8) | *(byte*)(s.strm.next_in);
s.bsLive += 8;
s.strm.next_in++;
s.strm.avail_in--;
s.strm.total_in_lo32++;
if (s.strm.total_in_lo32 == 0)
s.strm.total_in_hi32++;
}
s.storedCombinedCRC = (s.storedCombinedCRC << 8) | ((uint)uc);
s.state = BZ_X_IDLE;
retVal = BZ_STREAM_END;
goto save_state_and_return;
}
save_state_and_return:
s.save_i = i;
s.save_j = j;
s.save_t = t;
s.save_alphaSize = alphaSize;
s.save_nGroups = nGroups;
s.save_nSelectors = nSelectors;
s.save_EOB = EOB;
s.save_groupNo = groupNo;
s.save_groupPos = groupPos;
s.save_nextSym = nextSym;
s.save_nblockMAX = nblockMAX;
s.save_nblock = nblock;
s.save_es = es;
s.save_N = N;
s.save_curr = curr;
s.save_zt = zt;
s.save_zn = zn;
s.save_zvec = zvec;
s.save_zj = zj;
s.save_gSel = gSel;
s.save_gMinlen = gMinlen;
s.save_gLimit = gLimit;
s.save_gBase = gBase;
s.save_gPerm = gPerm;
return retVal;
}
#region Helpers
private static int BZ2_indexIntoF(int indx, int* cftab)
{
int nb, na, mid;
nb = 0;
na = 256;
do
{
mid = (nb + na) >> 1;
if (indx >= cftab[mid])
nb = mid;
else
na = mid;
} while (na - nb != 1);
return nb;
}
#endregion
}
}