(ArcOpener): use XoredStream+LzssStream composition instead of custom LZSS method.

This commit is contained in:
morkt 2017-01-18 05:17:04 +04:00
parent 7b1f237448
commit 0fe31c60eb

View File

@ -123,68 +123,7 @@ namespace GameRes.Formats.AST
return new XoredStream (input, 0xFF); return new XoredStream (input, 0xFF);
return input; return input;
} }
using (input) return new XoredStream (new LzssStream (input), 0xFF);
{
var data = UnpackLzss (input, pent.Size, pent.UnpackedSize);
return new BinMemoryStream (data, entry.Name);
}
}
byte[] UnpackLzss (Stream input, uint input_size, uint output_size)
{
var output = new byte[output_size];
var frame = new byte[0x1000];
int frame_pos = 0xFEE;
const int frame_mask = 0xFFF;
int dst = 0;
int remaining = (int)input_size;
int ctl = 2;
while (dst < output.Length)
{
ctl >>= 1;
if (1 == ctl)
{
if (remaining <= 0)
break;
ctl = input.ReadByte();
if (-1 == ctl)
break;
--remaining;
ctl |= 0x100;
}
if (0 != (ctl & 1))
{
int b = input.ReadByte();
if (-1 == b)
break;
--remaining;
frame[frame_pos++] = output[dst++] = (byte)~b;
frame_pos &= frame_mask;
}
else
{
if (remaining < 2)
break;
int lo = input.ReadByte();
int hi = input.ReadByte();
if (-1 == hi)
break;
remaining -= 2;
int offset = (hi & 0xf0) << 4 | lo;
for (int count = 3 + (hi & 0xF); count != 0; --count)
{
if (dst >= output.Length)
break;
byte v = frame[offset++];
offset &= frame_mask;
frame[frame_pos++] = v;
frame_pos &= frame_mask;
output[dst++] = v;
}
}
}
return output;
} }
} }
} }