AxibugEmuOnline/OtherCore/MyNes.Standard2/MyNes.Core/ComponentAce.Compression.Libs.zlib/Inflate.cs

410 lines
8.9 KiB
C#
Raw Normal View History

2024-07-24 15:03:33 +08:00
namespace ComponentAce.Compression.Libs.zlib
{
internal sealed class Inflate
{
private const int MAX_WBITS = 15;
private const int PRESET_DICT = 32;
internal const int Z_NO_FLUSH = 0;
internal const int Z_PARTIAL_FLUSH = 1;
internal const int Z_SYNC_FLUSH = 2;
internal const int Z_FULL_FLUSH = 3;
internal const int Z_FINISH = 4;
private const int Z_DEFLATED = 8;
private const int Z_OK = 0;
private const int Z_STREAM_END = 1;
private const int Z_NEED_DICT = 2;
private const int Z_ERRNO = -1;
private const int Z_STREAM_ERROR = -2;
private const int Z_DATA_ERROR = -3;
private const int Z_MEM_ERROR = -4;
private const int Z_BUF_ERROR = -5;
private const int Z_VERSION_ERROR = -6;
private const int METHOD = 0;
private const int FLAG = 1;
private const int DICT4 = 2;
private const int DICT3 = 3;
private const int DICT2 = 4;
private const int DICT1 = 5;
private const int DICT0 = 6;
private const int BLOCKS = 7;
private const int CHECK4 = 8;
private const int CHECK3 = 9;
private const int CHECK2 = 10;
private const int CHECK1 = 11;
private const int DONE = 12;
private const int BAD = 13;
internal int mode;
internal int method;
internal long[] was = new long[1];
internal long need;
internal int marker;
internal int nowrap;
internal int wbits;
internal InfBlocks blocks;
private static byte[] mark = new byte[4]
{
0,
0,
(byte)SupportClass.Identity(255L),
(byte)SupportClass.Identity(255L)
};
internal int inflateReset(ZStream z)
{
if (z == null || z.istate == null)
{
return -2;
}
z.total_in = (z.total_out = 0L);
z.msg = null;
z.istate.mode = ((z.istate.nowrap != 0) ? 7 : 0);
z.istate.blocks.reset(z, null);
return 0;
}
internal int inflateEnd(ZStream z)
{
if (blocks != null)
{
blocks.free(z);
}
blocks = null;
return 0;
}
internal int inflateInit(ZStream z, int w)
{
z.msg = null;
blocks = null;
nowrap = 0;
if (w < 0)
{
w = -w;
nowrap = 1;
}
if (w < 8 || w > 15)
{
inflateEnd(z);
return -2;
}
wbits = w;
z.istate.blocks = new InfBlocks(z, (z.istate.nowrap != 0) ? null : this, 1 << w);
inflateReset(z);
return 0;
}
internal int inflate(ZStream z, int f)
{
if (z == null || z.istate == null || z.next_in == null)
{
return -2;
}
f = ((f == 4) ? (-5) : 0);
int num = -5;
while (true)
{
switch (z.istate.mode)
{
case 0:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xF) != 8)
{
z.istate.mode = 13;
z.msg = "unknown compression method";
z.istate.marker = 5;
break;
}
if ((z.istate.method >> 4) + 8 > z.istate.wbits)
{
z.istate.mode = 13;
z.msg = "invalid window size";
z.istate.marker = 5;
break;
}
z.istate.mode = 1;
goto case 1;
case 1:
{
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
int num2 = z.next_in[z.next_in_index++] & 0xFF;
if (((z.istate.method << 8) + num2) % 31 != 0)
{
z.istate.mode = 13;
z.msg = "incorrect header check";
z.istate.marker = 5;
break;
}
if ((num2 & 0x20) == 0)
{
z.istate.mode = 7;
break;
}
z.istate.mode = 2;
goto case 2;
}
case 2:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need = ((z.next_in[z.next_in_index++] & 0xFF) << 24) & -16777216;
z.istate.mode = 3;
goto case 3;
case 3:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 16) & 0xFF0000uL);
z.istate.mode = 4;
goto case 4;
case 4:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 8) & 0xFF00uL);
z.istate.mode = 5;
goto case 5;
case 5:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need += (long)((ulong)z.next_in[z.next_in_index++] & 0xFFuL);
z.adler = z.istate.need;
z.istate.mode = 6;
return 2;
case 6:
z.istate.mode = 13;
z.msg = "need dictionary";
z.istate.marker = 0;
return -2;
case 7:
num = z.istate.blocks.proc(z, num);
switch (num)
{
case -3:
z.istate.mode = 13;
z.istate.marker = 0;
goto end_IL_0031;
case 0:
num = f;
break;
}
if (num != 1)
{
return num;
}
num = f;
z.istate.blocks.reset(z, z.istate.was);
if (z.istate.nowrap != 0)
{
z.istate.mode = 12;
break;
}
z.istate.mode = 8;
goto case 8;
case 8:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need = ((z.next_in[z.next_in_index++] & 0xFF) << 24) & -16777216;
z.istate.mode = 9;
goto case 9;
case 9:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 16) & 0xFF0000uL);
z.istate.mode = 10;
goto case 10;
case 10:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 8) & 0xFF00uL);
z.istate.mode = 11;
goto case 11;
case 11:
if (z.avail_in == 0)
{
return num;
}
num = f;
z.avail_in--;
z.total_in++;
z.istate.need += (long)((ulong)z.next_in[z.next_in_index++] & 0xFFuL);
if ((int)z.istate.was[0] != (int)z.istate.need)
{
z.istate.mode = 13;
z.msg = "incorrect data check";
z.istate.marker = 5;
break;
}
z.istate.mode = 12;
goto case 12;
case 12:
return 1;
case 13:
return -3;
default:
{
return -2;
}
end_IL_0031:
break;
}
}
}
internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength)
{
int start = 0;
int num = dictLength;
if (z == null || z.istate == null || z.istate.mode != 6)
{
return -2;
}
if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler)
{
return -3;
}
z.adler = z._adler.adler32(0L, null, 0, 0);
if (num >= 1 << z.istate.wbits)
{
num = (1 << z.istate.wbits) - 1;
start = dictLength - num;
}
z.istate.blocks.set_dictionary(dictionary, start, num);
z.istate.mode = 7;
return 0;
}
internal int inflateSync(ZStream z)
{
if (z == null || z.istate == null)
{
return -2;
}
if (z.istate.mode != 13)
{
z.istate.mode = 13;
z.istate.marker = 0;
}
int num;
if ((num = z.avail_in) == 0)
{
return -5;
}
int num2 = z.next_in_index;
int num3 = z.istate.marker;
while (num != 0 && num3 < 4)
{
num3 = ((z.next_in[num2] != mark[num3]) ? ((z.next_in[num2] == 0) ? (4 - num3) : 0) : (num3 + 1));
num2++;
num--;
}
z.total_in += num2 - z.next_in_index;
z.next_in_index = num2;
z.avail_in = num;
z.istate.marker = num3;
if (num3 != 4)
{
return -3;
}
long total_in = z.total_in;
long total_out = z.total_out;
inflateReset(z);
z.total_in = total_in;
z.total_out = total_out;
z.istate.mode = 7;
return 0;
}
internal int inflateSyncPoint(ZStream z)
{
if (z == null || z.istate == null || z.istate.blocks == null)
{
return -2;
}
return z.istate.blocks.sync_point();
}
}
}