Я пытаюсь перепроектировать алгоритм декомпрессии LZ1/LZ77. Длина выводимой области буфера/окна декодирования кодируется в файле как целое число переменной длины. Я прочитал все, что мог, о целочисленном кодировании переменной длины, и метод, используемый в этом случае, не похож ни на один другой, который я видел. Возможно, чтобы избежать проблем с патентами или, может быть, просто чтобы запутать. Включенный код может быть не совсем полным, но на данный момент он работает как минимум с несколькими файлами.
Я не понимаю, как, если вообще возможно, формулы, используемые ниже, могут быть сведены к чему-то более простому. Большинство алгоритмов целочисленного кодирования переменной длины используют какой-то цикл, но для этого я не смог этого сделать, потому что формула просто не кажется последовательной при оценке каждого полубайта.
Предложения приветствуются.
private static int getLength(BitReader bitStream)
{
const int minSize = 2;
int length = 0;
byte nibble3, nibble2, nibble1;
nibble3 = bitStream.ReadNibble();
if (nibble3 >= 0xc)
{
nibble2 = bitStream.ReadNibble();
nibble1 = bitStream.ReadNibble();
if (nibble3 == 0xF & nibble2 == 0xF & nibble1 == 0xF) return -1;
if ((nibble3 & 2) != 0)
{
length = (((((nibble3 & 7) + 3) << 6) + 8)) +
((nibble2 & 7) << 3) + nibble1 + minSize;
}
else if ((nibble3 & 1) != 0)
{
length = (((nibble3 & 7) << 6) + 8) +
((((nibble2 & 7)) + 1) << 3) + nibble1 + minSize;
}
else
{
length = ((((nibble3 & 7) << 4) + 8)) +
((nibble2 & 7) << 4) + nibble1 + minSize;
}
}
else if ((nibble3 & 8) != 0)
{
nibble1 = bitStream.ReadNibble();
length = ((((nibble3 & 7) << 1) + 1) << 3) + nibble1 + minSize;
}
else
{
length = nibble3 + minSize;
}
return length;
}