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

342 lines
9.7 KiB
C#

using System;
namespace ComponentAce.Compression.Libs.zlib
{
internal sealed class Tree
{
private const int MAX_BITS = 15;
private const int BL_CODES = 19;
private const int D_CODES = 30;
private const int LITERALS = 256;
private const int LENGTH_CODES = 29;
private static readonly int L_CODES = 286;
private static readonly int HEAP_SIZE = 2 * L_CODES + 1;
internal const int MAX_BL_BITS = 7;
internal const int END_BLOCK = 256;
internal const int REP_3_6 = 16;
internal const int REPZ_3_10 = 17;
internal const int REPZ_11_138 = 18;
internal static readonly int[] extra_lbits = new int[29]
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
4, 4, 4, 4, 5, 5, 5, 5, 0
};
internal static readonly int[] extra_dbits = new int[30]
{
0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12, 13, 13
};
internal static readonly int[] extra_blbits = new int[19]
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 3, 7
};
internal static readonly byte[] bl_order = new byte[19]
{
16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
11, 4, 12, 3, 13, 2, 14, 1, 15
};
internal const int Buf_size = 16;
internal const int DIST_CODE_LEN = 512;
internal static readonly byte[] _dist_code = new byte[512]
{
0, 1, 2, 3, 4, 4, 5, 5, 6, 6,
6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
18, 18, 19, 19, 20, 20, 20, 20, 21, 21,
21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29
};
internal static readonly byte[] _length_code = new byte[256]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
13, 13, 13, 13, 14, 14, 14, 14, 15, 15,
15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
17, 17, 17, 17, 17, 17, 17, 17, 18, 18,
18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
19, 19, 19, 19, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 28
};
internal static readonly int[] base_length = new int[29]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 10,
12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
64, 80, 96, 112, 128, 160, 192, 224, 0
};
internal static readonly int[] base_dist = new int[30]
{
0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
};
internal short[] dyn_tree;
internal int max_code;
internal StaticTree stat_desc;
internal static int d_code(int dist)
{
if (dist >= 256)
{
return _dist_code[256 + SupportClass.URShift(dist, 7)];
}
return _dist_code[dist];
}
internal void gen_bitlen(Deflate s)
{
short[] array = dyn_tree;
short[] static_tree = stat_desc.static_tree;
int[] extra_bits = stat_desc.extra_bits;
int extra_base = stat_desc.extra_base;
int max_length = stat_desc.max_length;
int num = 0;
for (int i = 0; i <= 15; i++)
{
s.bl_count[i] = 0;
}
array[s.heap[s.heap_max] * 2 + 1] = 0;
int j;
for (j = s.heap_max + 1; j < HEAP_SIZE; j++)
{
int num2 = s.heap[j];
int i = array[array[num2 * 2 + 1] * 2 + 1] + 1;
if (i > max_length)
{
i = max_length;
num++;
}
array[num2 * 2 + 1] = (short)i;
if (num2 <= max_code)
{
s.bl_count[i]++;
int num3 = 0;
if (num2 >= extra_base)
{
num3 = extra_bits[num2 - extra_base];
}
short num4 = array[num2 * 2];
s.opt_len += num4 * (i + num3);
if (static_tree != null)
{
s.static_len += num4 * (static_tree[num2 * 2 + 1] + num3);
}
}
}
if (num == 0)
{
return;
}
do
{
int i = max_length - 1;
while (s.bl_count[i] == 0)
{
i--;
}
s.bl_count[i]--;
s.bl_count[i + 1] = (short)(s.bl_count[i + 1] + 2);
s.bl_count[max_length]--;
num -= 2;
}
while (num > 0);
for (int i = max_length; i != 0; i--)
{
int num2 = s.bl_count[i];
while (num2 != 0)
{
int num5 = s.heap[--j];
if (num5 <= max_code)
{
if (array[num5 * 2 + 1] != i)
{
s.opt_len = (int)(s.opt_len + ((long)i - (long)array[num5 * 2 + 1]) * array[num5 * 2]);
array[num5 * 2 + 1] = (short)i;
}
num2--;
}
}
}
}
internal void build_tree(Deflate s)
{
short[] array = dyn_tree;
short[] static_tree = stat_desc.static_tree;
int elems = stat_desc.elems;
int num = -1;
s.heap_len = 0;
s.heap_max = HEAP_SIZE;
for (int i = 0; i < elems; i++)
{
if (array[i * 2] != 0)
{
num = (s.heap[++s.heap_len] = i);
s.depth[i] = 0;
}
else
{
array[i * 2 + 1] = 0;
}
}
int num2;
while (s.heap_len < 2)
{
num2 = (s.heap[++s.heap_len] = ((num < 2) ? (++num) : 0));
array[num2 * 2] = 1;
s.depth[num2] = 0;
s.opt_len--;
if (static_tree != null)
{
s.static_len -= static_tree[num2 * 2 + 1];
}
}
max_code = num;
for (int i = s.heap_len / 2; i >= 1; i--)
{
s.pqdownheap(array, i);
}
num2 = elems;
do
{
int i = s.heap[1];
s.heap[1] = s.heap[s.heap_len--];
s.pqdownheap(array, 1);
int num3 = s.heap[1];
s.heap[--s.heap_max] = i;
s.heap[--s.heap_max] = num3;
array[num2 * 2] = (short)(array[i * 2] + array[num3 * 2]);
s.depth[num2] = (byte)(Math.Max(s.depth[i], s.depth[num3]) + 1);
array[i * 2 + 1] = (array[num3 * 2 + 1] = (short)num2);
s.heap[1] = num2++;
s.pqdownheap(array, 1);
}
while (s.heap_len >= 2);
s.heap[--s.heap_max] = s.heap[1];
gen_bitlen(s);
gen_codes(array, num, s.bl_count);
}
internal static void gen_codes(short[] tree, int max_code, short[] bl_count)
{
short[] array = new short[16];
short num = 0;
for (int i = 1; i <= 15; i++)
{
num = (array[i] = (short)(num + bl_count[i - 1] << 1));
}
for (int j = 0; j <= max_code; j++)
{
int num2 = tree[j * 2 + 1];
if (num2 != 0)
{
tree[j * 2] = (short)bi_reverse(array[num2]++, num2);
}
}
}
internal static int bi_reverse(int code, int len)
{
int num = 0;
do
{
num |= code & 1;
code = SupportClass.URShift(code, 1);
num <<= 1;
}
while (--len > 0);
return SupportClass.URShift(num, 1);
}
}
}