Я пытаюсь перепроектировать алгоритм распаковки 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;
}
Оказывается, используемый алгоритм целочисленного кодирования переменной длины очень похож на метод Целочисленного кодирования переменной длины Длугоша. Действительно, требуется несколько вычислений, а не одна формула.
Исходя из этого, я переписал код следующим образом. Я все еще пытаюсь выяснить точный формат механизма, в котором используется ведущий 0xFFF.
private static int getLength(BitReader bitStream)
{
const int minSize = 2;
int length = 0;
byte nibble3, nibble2, nibble1;
byte nibble;
nibble = bitStream.ReadNibble();
if (nibble == 0xF)
{
nibble2 = bitStream.ReadNibble();
nibble1 = bitStream.ReadNibble();
if (nibble2 == 0xf && nibble1 == 0xF)
{
//The next nibble specifies the number of nibbles to be read, maybe.
byte nibblesToRead = (byte) (bitStream.ReadNibble()) ;
//The Dlugosz' mechanism would use a mask on the value but that doesn't appear to be the case here.
//nibblesToRead &= 7;
//switch (nibblesToRead & 7){
// case 0: nibblesToRead = 5; break;
// case 1: nibblesToRead = 8; break;
// case 2: nibblesToRead = 16; break;
//}
byte value=0;
byte[] values = new byte[nibblesToRead];
bool c=true;
for (int i = 0; i < nibblesToRead; i++)
{
value = bitStream.ReadNibble();
//values[i] = value;
length += (((value << 1) | 1) << 3);
}
value = bitStream.ReadNibble();
length += value;
}
}
else if((nibble >= 0xC)){
nibble2 = bitStream.ReadNibble();
nibble1 = bitStream.ReadNibble();
length = ((((((nibble & 1) <<1)|1))<< 3) + ((nibble2<<1)|1)<<3)+nibble1;
}
else if ((nibble & 8)!=0){
nibble1 = bitStream.ReadNibble();
length = ((((nibble & 3)<<1) | 1) << 3) + nibble1;
}
else{
length=nibble;
}
return length + minSize;
};