mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-13 05:35:24 +00:00
2194 lines
82 KiB
C#
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
|
|
}
|
|
} |