Files
Aerofoil/unpacktool/StuffIt13Decompressor.cpp

494 lines
15 KiB
C++

#include "StuffIt13Decompressor.h"
#include "CSInputBuffer.h"
#include "PrefixCode.h"
static const int FirstCodeLengths_1[321] =
{
4, 5, 7, 8, 8, 9, 9, 9, 9, 7, 9, 9, 9, 8, 9, 9,
9, 9, 9, 9, 9, 9, 9,10, 9, 9,10,10, 9,10, 9, 9,
5, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 7, 9,
9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 8, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 7, 8, 9,
7, 9, 9, 7, 7, 9, 9, 9, 9,10, 9,10,10,10, 9, 9,
9, 5, 9, 8, 7, 5, 9, 8, 8, 7, 9, 9, 8, 8, 5, 5,
7,10, 5, 8, 5, 8, 9, 9, 9, 9, 9,10, 9, 9,10, 9,
9,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,10,
9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
9,10,10,10,10,10,10,10, 9, 9,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,
9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
9,10,10,10,10,10,10,10,10,10,10,10, 9, 9,10,10,
9,10,10,10,10,10,10,10, 9,10,10,10, 9,10, 9, 5,
6, 5, 5, 8, 9, 9, 9, 9, 9, 9,10,10,10, 9,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10, 9,10, 9, 9, 9,10, 9,10, 9,10, 9,10, 9,
10,10,10, 9,10, 9,10,10, 9, 9, 9, 6, 9, 9,10, 9,
5,
};
static const int SecondCodeLengths_1[321] =
{
4, 5, 6, 6, 7, 7, 6, 7, 7, 7, 6, 8, 7, 8, 8, 8,
8, 9, 6, 9, 8, 9, 8, 9, 9, 9, 8,10, 5, 9, 7, 9,
6, 9, 8,10, 9,10, 8, 8, 9, 9, 7, 9, 8, 9, 8, 9,
8, 8, 6, 9, 9, 8, 8, 9, 9,10, 8, 9, 9,10, 8,10,
8, 8, 8, 8, 8, 9, 7,10, 6, 9, 9,11, 7, 8, 8, 9,
8,10, 7, 8, 6, 9,10, 9, 9,10, 8,11, 9,11, 9,10,
9, 8, 9, 8, 8, 8, 8,10, 9, 9,10,10, 8, 9, 8, 8,
8,11, 9, 8, 8, 9, 9,10, 8,11,10,10, 8,10, 9,10,
8, 9, 9,11, 9,11, 9,10,10,11,10,12, 9,12,10,11,
10,11, 9,10,10,11,10,11,10,11,10,11,10,10,10, 9,
9, 9, 8, 7, 6, 8,11,11, 9,12,10,12, 9,11,11,11,
10,12,11,11,10,12,10,11,10,10,10,11,10,11,11,11,
9,12,10,12,11,12,10,11,10,12,11,12,11,12,11,12,
10,12,11,12,11,11,10,12,10,11,10,12,10,12,10,12,
10,11,11,11,10,11,11,11,10,12,11,12,10,10,11,11,
9,12,11,12,10,11,10,12,10,11,10,12,10,11,10, 7,
5, 4, 6, 6, 7, 7, 7, 8, 8, 7, 7, 6, 8, 6, 7, 7,
9, 8, 9, 9,10,11,11,11,12,11,10,11,12,11,12,11,
12,12,12,12,11,12,12,11,12,11,12,11,13,11,12,10,
13,10,14,14,13,14,15,14,16,15,15,18,18,18, 9,18,
8,
};
static const int OffsetCodeLengths_1[11] =
{
5, 6, 3, 3, 3, 3, 3, 3, 3, 4, 6,
};
static const int FirstCodeLengths_2[321] =
{
4, 7, 7, 8, 7, 8, 8, 8, 8, 7, 8, 7, 8, 7, 9, 8,
8, 8, 9, 9, 9, 9,10,10, 9,10,10,10,10,10, 9, 9,
5, 9, 8, 9, 9,11,10, 9, 8, 9, 9, 9, 8, 9, 7, 8,
8, 8, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9,10, 9,
8, 8, 7, 7, 7, 8, 8, 9, 8, 8, 9, 9, 8, 8, 7, 8,
7,10, 8, 7, 7, 9, 9, 9, 9,10,10,11,11,11,10, 9,
8, 6, 8, 7, 7, 5, 7, 7, 7, 6, 9, 8, 6, 7, 6, 6,
7, 9, 6, 6, 6, 7, 8, 8, 8, 8, 9,10, 9,10, 9, 9,
8, 9,10,10, 9,10,10, 9, 9,10,10,10,10,10,10,10,
9,10,10,11,10,10,10,10,10,10,10,11,10,11,10,10,
9,11,10,10,10,10,10,10, 9, 9,10,11,10,11,10,11,
10,12,10,11,10,12,11,12,10,12,10,11,10,11,11,11,
9,10,11,11,11,12,12,10,10,10,11,11,10,11,10,10,
9,11,10,11,10,11,11,11,10,11,11,12,11,11,10,10,
10,11,10,10,11,11,12,10,10,11,11,12,11,11,10,11,
9,12,10,11,11,11,10,11,10,11,10,11, 9,10, 9, 7,
3, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9,11,10,10,10,
12,13,11,12,12,11,13,12,12,11,12,12,13,12,14,13,
14,13,15,13,14,15,15,14,13,15,15,14,15,14,15,15,
14,15,13,13,14,15,15,14,14,16,16,15,15,15,12,15,
10,
};
static const int SecondCodeLengths_2[321] =
{
5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 7, 8, 7, 7,
7, 8, 8, 8, 8, 9, 8, 9, 8, 9, 9, 9, 7, 9, 8, 8,
6, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 8,
8, 8, 8, 9, 8, 9, 8, 9, 9,10, 8,10, 8, 9, 9, 8,
8, 8, 7, 8, 8, 9, 8, 9, 7, 9, 8,10, 8, 9, 8, 9,
8, 9, 8, 8, 8, 9, 9, 9, 9,10, 9,11, 9,10, 9,10,
8, 8, 8, 9, 8, 8, 8, 9, 9, 8, 9,10, 8, 9, 8, 8,
8,11, 8, 7, 8, 9, 9, 9, 9,10, 9,10, 9,10, 9, 8,
8, 9, 9,10, 9,10, 9,10, 8,10, 9,10, 9,11,10,11,
9,11,10,10,10,11, 9,11, 9,10, 9,11, 9,11,10,10,
9,10, 9, 9, 8,10, 9,11, 9, 9, 9,11,10,11, 9,11,
9,11, 9,11,10,11,10,11,10,11, 9,10,10,11,10,10,
8,10, 9,10,10,11, 9,11, 9,10,10,11, 9,10,10, 9,
9,10, 9,10, 9,10, 9,10, 9,11, 9,11,10,10, 9,10,
9,11, 9,11, 9,11, 9,10, 9,11, 9,11, 9,11, 9,10,
8,11, 9,10, 9,10, 9,10, 8,10, 8, 9, 8, 9, 8, 7,
4, 4, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 7, 8, 8,
9, 9,10,10,10,10,10,10,11,11,10,10,12,11,11,12,
12,11,12,12,11,12,12,12,12,12,12,11,12,11,13,12,
13,12,13,14,14,14,15,13,14,13,14,18,18,17, 7,16,
9,
};
static const int OffsetCodeLengths_2[13] =
{
5, 6, 4, 4, 3, 3, 3, 3, 3, 4, 4, 4, 6,
};
static const int FirstCodeLengths_3[321] =
{
6, 6, 6, 6, 6, 9, 8, 8, 4, 9, 8, 9, 8, 9, 9, 9,
8, 9, 9,10, 8,10,10,10, 9,10,10,10, 9,10,10, 9,
9, 9, 8,10, 9,10, 9,10, 9,10, 9,10, 9, 9, 8, 9,
8, 9, 9, 9,10,10,10,10, 9, 9, 9,10, 9,10, 9, 9,
7, 8, 8, 9, 8, 9, 9, 9, 8, 9, 9,10, 9, 9, 8, 9,
8, 9, 8, 8, 8, 9, 9, 9, 9, 9,10,10,10,10,10, 9,
8, 8, 9, 8, 9, 7, 8, 8, 9, 8,10,10, 8, 9, 8, 8,
8,10, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10, 9,
7, 9, 9,10,10,10,10,10, 9,10,10,10,10,10,10, 9,
9,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,
9,10,10,10,10,10,10,10, 9, 9, 9,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10, 9,
8, 9,10,10,10,10,10,10,10,10,10,10, 9,10,10,10,
9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
9,10,10,10,10,10,10, 9,10,10,10,10,10,10, 9, 9,
9,10,10,10,10,10,10, 9, 9,10, 9, 9, 8, 9, 8, 9,
4, 6, 6, 6, 7, 8, 8, 9, 9,10,10,10, 9,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10, 7,10,
10,10, 7,10,10, 7, 7, 7, 7, 7, 6, 7,10, 7, 7,10,
7, 7, 7, 6, 7, 6, 6, 7, 7, 6, 6, 9, 6, 9,10, 6,
10,
};
static const int SecondCodeLengths_3[321] =
{
5, 6, 6, 6, 6, 7, 7, 7, 6, 8, 7, 8, 7, 9, 8, 8,
7, 7, 8, 9, 9, 9, 9,10, 8, 9, 9,10, 8,10, 9, 8,
6,10, 8,10, 8,10, 9, 9, 9, 9, 9,10, 9, 9, 8, 9,
8, 9, 8, 9, 9,10, 9,10, 9, 9, 8,10, 9,11,10, 8,
8, 8, 8, 9, 7, 9, 9,10, 8, 9, 8,11, 9,10, 9,10,
8, 9, 9, 9, 9, 8, 9, 9,10,10,10,12,10,11,10,10,
8, 9, 9, 9, 8, 9, 8, 8,10, 9,10,11, 8,10, 9, 9,
8,12, 8, 9, 9, 9, 9, 8, 9,10, 9,12,10,10,10, 8,
7,11,10, 9,10,11, 9,11, 7,11,10,12,10,12,10,11,
9,11, 9,12,10,12,10,12,10, 9,11,12,10,12,10,11,
9,10, 9,10, 9,11,11,12, 9,10, 8,12,11,12, 9,12,
10,12,10,13,10,12,10,12,10,12,10, 9,10,12,10, 9,
8,11,10,12,10,12,10,12,10,11,10,12, 8,12,10,11,
10,10,10,12, 9,11,10,12,10,12,11,12,10, 9,10,12,
9,10,10,12,10,11,10,11,10,12, 8,12, 9,12, 8,12,
8,11,10,11,10,11, 9,10, 8,10, 9, 9, 8, 9, 8, 7,
4, 3, 5, 5, 6, 5, 6, 6, 7, 7, 8, 8, 8, 7, 7, 7,
9, 8, 9, 9,11, 9,11, 9, 8, 9, 9,11,12,11,12,12,
13,13,12,13,14,13,14,13,14,13,13,13,12,13,13,12,
13,13,14,14,13,13,14,14,14,14,15,18,17,18, 8,16,
10,
};
static const int OffsetCodeLengths_3[14] =
{
6, 7, 4, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7,
};
static const int FirstCodeLengths_4[321] =
{
2, 6, 6, 7, 7, 8, 7, 8, 7, 8, 8, 9, 8, 9, 9, 9,
8, 8, 9, 9, 9,10,10, 9, 8,10, 9,10, 9,10, 9, 9,
6, 9, 8, 9, 9,10, 9, 9, 9,10, 9, 9, 9, 9, 8, 8,
8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,
7, 7, 8, 8, 8, 8, 9, 9, 7, 8, 9,10, 8, 8, 7, 8,
8,10, 8, 8, 8, 9, 8, 9, 9,10, 9,11,10,11, 9, 9,
8, 7, 9, 8, 8, 6, 8, 8, 8, 7,10, 9, 7, 8, 7, 7,
8,10, 7, 7, 7, 8, 9, 9, 9, 9,10,11, 9,11,10, 9,
7, 9,10,10,10,11,11,10,10,11,10,10,10,11,11,10,
9,10,10,11,10,11,10,11,10,10,10,11,10,11,10,10,
9,10,10,11,10,10,10,10, 9,10,10,10,10,11,10,11,
10,11,10,11,11,11,10,12,10,11,10,11,10,11,11,10,
8,10,10,11,10,11,11,11,10,11,10,11,10,11,11,11,
9,10,11,11,10,11,11,11,10,11,11,11,10,10,10,10,
10,11,10,10,11,11,10,10, 9,11,10,10,11,11,10,10,
10,11,10,10,10,10,10,10, 9,11,10,10, 8,10, 8, 6,
5, 6, 6, 7, 7, 8, 8, 8, 9,10,11,10,10,11,11,12,
12,10,11,12,12,12,12,13,13,13,13,13,12,13,13,15,
14,12,14,15,16,12,12,13,15,14,16,15,17,18,15,17,
16,15,15,15,15,13,13,10,14,12,13,17,17,18,10,17,
4,
};
static const int SecondCodeLengths_4[321] =
{
4, 5, 6, 6, 6, 6, 7, 7, 6, 7, 7, 9, 6, 8, 8, 7,
7, 8, 8, 8, 6, 9, 8, 8, 7, 9, 8, 9, 8, 9, 8, 9,
6, 9, 8, 9, 8,10, 9, 9, 8,10, 8,10, 8, 9, 8, 9,
8, 8, 7, 9, 9, 9, 9, 9, 8,10, 9,10, 9,10, 9, 8,
7, 8, 9, 9, 8, 9, 9, 9, 7,10, 9,10, 9, 9, 8, 9,
8, 9, 8, 8, 8, 9, 9,10, 9, 9, 8,11, 9,11,10,10,
8, 8,10, 8, 8, 9, 9, 9,10, 9,10,11, 9, 9, 9, 9,
8, 9, 8, 8, 8,10,10, 9, 9, 8,10,11,10,11,11, 9,
8, 9,10,11, 9,10,11,11, 9,12,10,10,10,12,11,11,
9,11,11,12, 9,11, 9,10,10,10,10,12, 9,11,10,11,
9,11,11,11,10,11,11,12, 9,10,10,12,11,11,10,11,
9,11,10,11,10,11, 9,11,11, 9, 8,11,10,11,11,10,
7,12,11,11,11,11,11,12,10,12,11,13,11,10,12,11,
10,11,10,11,10,11,11,11,10,12,11,11,10,11,10,10,
10,11,10,12,11,12,10,11, 9,11,10,11,10,11,10,12,
9,11,11,11, 9,11,10,10, 9,11,10,10, 9,10, 9, 7,
4, 5, 5, 5, 6, 6, 7, 6, 8, 7, 8, 9, 9, 7, 8, 8,
10, 9,10,10,12,10,11,11,11,11,10,11,12,11,11,11,
11,11,13,12,11,12,13,12,12,12,13,11, 9,12,13, 7,
13,11,13,11,10,11,13,15,15,12,14,15,15,15, 6,15,
5,
};
static const int OffsetCodeLengths_4[11] =
{
3, 6, 5, 4, 2, 3, 3, 3, 4, 4, 6,
};
static const int FirstCodeLengths_5[321] =
{
7, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 7, 9, 9,
9, 9, 9, 9, 9, 9, 9,10, 9,10, 9,10, 9,10, 9, 9,
5, 9, 7, 9, 9, 9, 9, 9, 7, 7, 7, 9, 7, 7, 8, 7,
8, 8, 7, 7, 9, 9, 9, 9, 7, 7, 7, 9, 9, 9, 9, 9,
9, 7, 9, 7, 7, 7, 7, 9, 9, 7, 9, 9, 7, 7, 7, 7,
7, 9, 7, 8, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 7, 8, 7, 7, 7, 8, 8, 6, 7, 9, 7, 7, 8, 7, 5,
6, 9, 5, 7, 5, 6, 7, 7, 9, 8, 9, 9, 9, 9, 9, 9,
9, 9,10, 9,10,10,10, 9, 9,10,10,10,10,10,10,10,
9,10,10,10,10,10,10,10,10,10,10,10, 9,10,10,10,
9,10,10,10, 9, 9,10, 9, 9, 9, 9,10,10,10,10,10,
10,10,10,10,10,10, 9,10,10,10,10,10,10,10,10,10,
9,10,10,10, 9,10,10,10, 9, 9, 9,10,10,10,10,10,
9,10, 9,10,10, 9,10,10, 9,10,10,10,10,10,10,10,
9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
9,10,10,10,10,10,10,10, 9,10, 9,10, 9,10,10, 9,
5, 6, 8, 8, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10, 9,10,10, 5,10, 8, 9, 8,
9,
};
static const int SecondCodeLengths_5[321] =
{
8,10,11,11,11,12,11,11,12, 6,11,12,10, 5,12,12,
12,12,12,12,12,13,13,14,13,13,12,13,12,13,12,15,
4,10, 7, 9,11,11,10, 9, 6, 7, 8, 9, 6, 7, 6, 7,
8, 7, 7, 8, 8, 8, 8, 8, 8, 9, 8, 7,10, 9,10,10,
11, 7, 8, 6, 7, 8, 8, 9, 8, 7,10,10, 8, 7, 8, 8,
7,10, 7, 6, 7, 9, 9, 8,11,11,11,10,11,11,11, 8,
11, 6, 7, 6, 6, 6, 6, 8, 7, 6,10, 9, 6, 7, 6, 6,
7,10, 6, 5, 6, 7, 7, 7,10, 8,11, 9,13, 7,14,16,
12,14,14,15,15,16,16,14,15,15,15,15,15,15,15,15,
14,15,13,14,14,16,15,17,14,17,15,17,12,14,13,16,
12,17,13,17,14,13,13,14,14,12,13,15,15,14,15,17,
14,17,15,14,15,16,12,16,15,14,15,16,15,16,17,17,
15,15,17,17,13,14,15,15,13,12,16,16,17,14,15,16,
15,15,13,13,15,13,16,17,15,17,17,17,16,17,14,17,
14,16,15,17,15,15,14,17,15,17,15,16,15,15,16,16,
14,17,17,15,15,16,15,17,15,14,16,16,16,16,16,12,
4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9,
9, 9, 9,10,10,10,11,10,11,11,11,11,11,12,12,12,
13,13,12,13,12,14,14,12,13,13,13,13,14,12,13,13,
14,14,14,13,14,14,15,15,13,15,13,17,17,17, 9,17,
7,
};
static const int OffsetCodeLengths_5[11] =
{
6, 7, 7, 6, 4, 3, 2, 2, 3, 3, 6,
};
static const int *FirstCodeLengths[5] =
{
FirstCodeLengths_1,FirstCodeLengths_2,FirstCodeLengths_3,FirstCodeLengths_4,FirstCodeLengths_5
};
static const int *SecondCodeLengths[5] =
{
SecondCodeLengths_1,SecondCodeLengths_2,SecondCodeLengths_3,SecondCodeLengths_4,SecondCodeLengths_5
};
static const int *OffsetCodeLengths[5] =
{
OffsetCodeLengths_1,OffsetCodeLengths_2,OffsetCodeLengths_3,OffsetCodeLengths_4,OffsetCodeLengths_5
};
static const int OffsetCodeSize[5] = { 11,13,14,11,11 };
static const int MetaCodes[37] =
{
0x5d8,0x058,0x040,0x0c0,0x000,0x078,0x02b,0x014,
0x00c,0x01c,0x01b,0x00b,0x010,0x020,0x038,0x018,
0x0d8,0xbd8,0x180,0x680,0x380,0xf80,0x780,0x480,
0x080,0x280,0x3d8,0xfd8,0x7d8,0x9d8,0x1d8,0x004,
0x001,0x002,0x007,0x003,0x008
};
static const int MetaCodeLengths[37] =
{
11,8,8,8,8,7,6,5,5,5,5,6,5,6,7,7,9,12,10,11,11,12,
12,11,11,11,12,12,12,12,12,5,2,2,3,4,5
};
StuffIt13Decompressor::StuffIt13Decompressor()
: LZSSDecompressor(65536)
, firstcodei(nullptr)
, secondcodei(nullptr)
, offsetcodei(nullptr)
, firstcoder(nullptr)
, secondcoder(nullptr)
, offsetcoder(nullptr)
{
}
StuffIt13Decompressor::~StuffIt13Decompressor()
{
delete firstcodei;
delete secondcodei;
delete offsetcodei;
}
bool StuffIt13Decompressor::resetLZSSHandle()
{
delete firstcodei;
delete secondcodei;
delete offsetcodei;
firstcodei = secondcodei = offsetcodei = nullptr;
firstcoder = secondcoder = offsetcoder = nullptr;
int val;
if (!CSInputNextByte(input, val))
return false;
int code = val >> 4;
if (code == 0)
{
XADPrefixCode *metacode = XADPrefixCode::prefixCode();
for (int i = 0; i < 37; i++)
metacode->addValueLowBitFirst(i, MetaCodes[i], MetaCodeLengths[i]);
firstcodei = firstcoder = this->allocAndParseCodeOfSize(321, metacode);
if (val & 0x08)
secondcoder = firstcoder;
else
secondcodei = secondcoder = this->allocAndParseCodeOfSize(321, metacode);
offsetcodei = offsetcoder = this->allocAndParseCodeOfSize((val & 0x07) + 10, metacode);
}
else if (code < 6)
{
firstcoder = firstcodei = XADPrefixCode::prefixCodeWithLengths(FirstCodeLengths[code - 1], 321, 32, true);
secondcoder = secondcodei = XADPrefixCode::prefixCodeWithLengths(SecondCodeLengths[code - 1], 321, 32, true);
offsetcoder = offsetcodei = XADPrefixCode::prefixCodeWithLengths(OffsetCodeLengths[code - 1], OffsetCodeSize[code - 1], 32, true);
}
else
return false;
currcode = firstcoder;
return true;
}
XADPrefixCode *StuffIt13Decompressor::allocAndParseCodeOfSize(int numcodes, XADPrefixCode *metacode)
{
int length = 0;
std::vector<int> lengths;
lengths.resize(numcodes);
for (int i = 0; i < numcodes; i++)
{
int val;
if (!CSInputNextSymbolUsingCodeLE(input, metacode, val))
return nullptr;
switch (val)
{
case 31: length = -1; break;
case 32: length++; break;
case 33: length--; break;
case 34:
{
unsigned int bit;
if (!CSInputNextBitLE(input, bit))
return nullptr;
if (bit)
lengths[i++] = length;
}
break;
case 35:
{
unsigned int bits;
if (!CSInputNextBitStringLE(input, 3, bits))
return nullptr;
val = bits + 2;
while (val--)
lengths[i++] = length;
}
break;
case 36:
{
unsigned int bits;
if (!CSInputNextBitStringLE(input, 6, bits))
return nullptr;
val = bits + 10;
while (val--)
lengths[i++] = length;
}
break;
default:
length = val + 1;
break;
}
lengths[i] = length;
}
return XADPrefixCode::prefixCodeWithLengths(lengths.data(), numcodes, 32, true);
}
bool StuffIt13Decompressor::nextLiteralOrOffset(int *offset, int *length, int &result)
{
int val;
if (!CSInputNextSymbolUsingCodeLE(input, currcode, val))
return false;
if (val < 0x100)
{
currcode = firstcoder;
result = val;
return true;
}
else
{
currcode = secondcoder;
if (val < 0x13e)
*length = val - 0x100 + 3;
else if (val == 0x13e)
{
unsigned int bits;
if (!CSInputNextBitStringLE(input, 10, bits))
return false;
*length = bits + 65;
}
else if (val == 0x13f)
{
unsigned int bits;
if (!CSInputNextBitStringLE(input, 15, bits))
return false;
*length = bits + 65;
}
else
{
result = XADLZSSEnd;
return true;
}
int bitlength;
if (!CSInputNextSymbolUsingCodeLE(input, offsetcoder, bitlength))
return false;
if (bitlength == 0)
*offset = 1;
else if (bitlength == 1)
*offset = 2;
else
{
unsigned int bits;
if (!CSInputNextBitStringLE(input, bitlength - 1, bits))
return false;
*offset = (1 << (bitlength - 1)) + bits + 1;
}
result = XADLZSSMatch;
return true;
}
}