81 lines
2.5 KiB
C#
81 lines
2.5 KiB
C#
namespace fxl.codes.kisekae.data.Archives;
|
|
|
|
/**
|
|
* Ported from https://github.com/kisekae/UltraKiss/blob/master/src/Kisekae/Lhhuf.java
|
|
*/
|
|
public class LhArchiveDecoder
|
|
{
|
|
private const int Buffer = 4096;
|
|
private const int BufferSize = 60;
|
|
private const int Threshold = 2;
|
|
private const int EndOfFile = -1;
|
|
private const int NChar = 256 - Threshold + BufferSize; // For some reason????
|
|
private const int TableSize = NChar * 2 - 1;
|
|
private const int RootPosition = TableSize - 1;
|
|
private const int MaxFreq = 0x8000;
|
|
private readonly int[] _child = new int[TableSize];
|
|
private readonly int[] _frequency = new int[TableSize];
|
|
private readonly int[] _parent = new int[TableSize + NChar];
|
|
|
|
private int _bytesProcessed;
|
|
private int[] _data = new int[Buffer + 1];
|
|
private int _lastBytesProcessed;
|
|
private int[] _leftChild = new int[Buffer + 1];
|
|
private int[] _rightChild = new int[Buffer * 2 + 1];
|
|
private int[] _same = new int[Buffer + 1];
|
|
private byte[] _textBuffer = new byte[Buffer + BufferSize - 1];
|
|
private int putlen, getlen, putbuf, getbuf;
|
|
|
|
private void Initialize()
|
|
{
|
|
for (var i = 0; i < NChar; i++)
|
|
{
|
|
_frequency[i] = 1;
|
|
_child[i] = i + TableSize;
|
|
_parent[i + TableSize] = i;
|
|
}
|
|
|
|
for (int i = 0, j = NChar; j <= RootPosition; i += 2, j++)
|
|
{
|
|
_frequency[j] = _frequency[i] + _frequency[i + 1];
|
|
_child[j] = i;
|
|
_parent[i] = _parent[i + 1] = j;
|
|
}
|
|
|
|
_frequency[TableSize] = 0xffff;
|
|
_parent[RootPosition] = 0;
|
|
}
|
|
|
|
private void Reconstruct()
|
|
{
|
|
int k;
|
|
for (int i = 0, j = 0; i < TableSize; i++, j++)
|
|
{
|
|
if (_child[i] < TableSize) continue;
|
|
|
|
_frequency[j] = (_frequency[i] + 1) / 2;
|
|
_child[j] = _child[i];
|
|
}
|
|
|
|
for (int i = 0, j = NChar; j < TableSize; i += 2, j++)
|
|
{
|
|
k = i + 1;
|
|
var f = _frequency[j] = _frequency[i] + _frequency[k];
|
|
for (k = j - 1; f < _frequency[k]; k--);
|
|
k++;
|
|
|
|
for (int p = j, e = k; p > e; p--) _frequency[p] = _frequency[p - 1];
|
|
_frequency[k] = f;
|
|
|
|
for (var p = j; p > k; p--) _child[p] = _child[p - 1];
|
|
_child[k] = i;
|
|
}
|
|
|
|
/* link parents */
|
|
for (var i = 0; i < TableSize; i++)
|
|
if ((k = _child[i]) >= TableSize)
|
|
_parent[k] = i;
|
|
else
|
|
_parent[k] = _parent[k + 1] = i;
|
|
}
|
|
} |