mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
(UnpackTpw): made into separate static method.
This commit is contained in:
@@ -235,76 +235,85 @@ namespace GameRes.Formats.Ankh
|
|||||||
|
|
||||||
Stream OpenTpw (ArcFile arc, PackedEntry entry)
|
Stream OpenTpw (ArcFile arc, PackedEntry entry)
|
||||||
{
|
{
|
||||||
var output = new byte[entry.UnpackedSize];
|
|
||||||
using (var input = arc.File.CreateStream (entry.Offset, entry.Size))
|
using (var input = arc.File.CreateStream (entry.Offset, entry.Size))
|
||||||
{
|
{
|
||||||
input.Position = 8;
|
var output = new byte[entry.UnpackedSize];
|
||||||
var offsets = new int[4];
|
UnpackTpw (input, output);
|
||||||
offsets[0] = input.ReadUInt16();
|
return new BinMemoryStream (output, entry.Name);
|
||||||
offsets[1] = offsets[0] * 2;
|
}
|
||||||
offsets[2] = offsets[0] * 3;
|
}
|
||||||
offsets[3] = offsets[0] * 4;
|
|
||||||
int dst = 0;
|
internal static void UnpackTpw (IBinaryStream input, byte[] output)
|
||||||
while (dst < output.Length)
|
{
|
||||||
|
input.Position = 8;
|
||||||
|
var offsets = new int[4];
|
||||||
|
offsets[0] = input.ReadUInt16();
|
||||||
|
offsets[1] = offsets[0] * 2;
|
||||||
|
offsets[2] = offsets[0] * 3;
|
||||||
|
offsets[3] = offsets[0] * 4;
|
||||||
|
int dst = 0;
|
||||||
|
while (dst < output.Length)
|
||||||
|
{
|
||||||
|
byte ctl = input.ReadUInt8();
|
||||||
|
if (0 == ctl)
|
||||||
|
break;
|
||||||
|
int remaining = output.Length - dst;
|
||||||
|
int count;
|
||||||
|
if (ctl < 0x40)
|
||||||
{
|
{
|
||||||
byte ctl = input.ReadUInt8();
|
count = Math.Min (ctl, remaining);
|
||||||
if (0 == ctl)
|
input.Read (output, dst, count);
|
||||||
break;
|
dst += count;
|
||||||
int count;
|
}
|
||||||
if (ctl < 0x40)
|
else if (ctl <= 0x6F)
|
||||||
{
|
{
|
||||||
count = Math.Min (ctl, output.Length - dst);
|
if (0x6F == ctl)
|
||||||
input.Read (output, dst, count);
|
count = input.ReadUInt16();
|
||||||
dst += count;
|
|
||||||
}
|
|
||||||
else if (ctl <= 0x6F)
|
|
||||||
{
|
|
||||||
if (0x6F == ctl)
|
|
||||||
count = input.ReadUInt16();
|
|
||||||
else
|
|
||||||
count = ctl - 0x3D;
|
|
||||||
byte v = input.ReadUInt8();
|
|
||||||
while (count --> 0)
|
|
||||||
output[dst++] = v;
|
|
||||||
}
|
|
||||||
else if (ctl <= 0x9F)
|
|
||||||
{
|
|
||||||
if (ctl == 0x9F)
|
|
||||||
count = input.ReadUInt16();
|
|
||||||
else
|
|
||||||
count = ctl - 0x6E;
|
|
||||||
byte v1 = input.ReadUInt8();
|
|
||||||
byte v2 = input.ReadUInt8();
|
|
||||||
while (count --> 0)
|
|
||||||
{
|
|
||||||
output[dst++] = v1;
|
|
||||||
output[dst++] = v2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ctl <= 0xBF)
|
|
||||||
{
|
|
||||||
if (ctl == 0xBF)
|
|
||||||
count = input.ReadUInt16();
|
|
||||||
else
|
|
||||||
count = ctl - 0x9E;
|
|
||||||
input.Read (output, dst, 3);
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
count *= 3;
|
|
||||||
Binary.CopyOverlapped (output, dst, dst+3, count-3);
|
|
||||||
dst += count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
count = (byte)(ctl - 0x3D);
|
||||||
|
count = Math.Min (count, remaining);
|
||||||
|
byte v = input.ReadUInt8();
|
||||||
|
while (count --> 0)
|
||||||
|
output[dst++] = v;
|
||||||
|
}
|
||||||
|
else if (ctl <= 0x9F)
|
||||||
|
{
|
||||||
|
if (ctl == 0x9F)
|
||||||
|
count = input.ReadUInt16();
|
||||||
|
else
|
||||||
|
count = (byte)(ctl - 0x6E);
|
||||||
|
dst += input.Read (output, dst, Math.Min (2, remaining));
|
||||||
|
--count;
|
||||||
|
if (count > 0 && remaining > 2)
|
||||||
{
|
{
|
||||||
count = (ctl & 0x3F) + 3;
|
count = Math.Min (count * 2, remaining - 2);
|
||||||
int offset = input.ReadUInt8();
|
Binary.CopyOverlapped (output, dst-2, dst, count);
|
||||||
offset = (offset & 0x3F) - offsets[offset >> 6];
|
|
||||||
Binary.CopyOverlapped (output, dst+offset, dst, count);
|
|
||||||
dst += count;
|
dst += count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new BinMemoryStream (output, entry.Name);
|
else if (ctl <= 0xBF)
|
||||||
|
{
|
||||||
|
if (ctl == 0xBF)
|
||||||
|
count = input.ReadUInt16();
|
||||||
|
else
|
||||||
|
count = (byte)(ctl - 0x9E);
|
||||||
|
dst += input.Read (output, dst, Math.Min (3, remaining));
|
||||||
|
--count;
|
||||||
|
if (count > 0 && remaining > 3)
|
||||||
|
{
|
||||||
|
count = Math.Min (count * 3, remaining - 3);
|
||||||
|
Binary.CopyOverlapped (output, dst-3, dst, count);
|
||||||
|
dst += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = Math.Min ((ctl & 0x3F) + 3, remaining);
|
||||||
|
int offset = input.ReadUInt8();
|
||||||
|
offset = (offset & 0x3F) - offsets[offset >> 6];
|
||||||
|
Binary.CopyOverlapped (output, dst+offset, dst, count);
|
||||||
|
dst += count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user