(UnpackTpw): made into separate static method.

This commit is contained in:
morkt
2023-09-07 11:51:19 +04:00
parent 42085dd468
commit ae24ef1cdc

View File

@@ -235,8 +235,15 @@ 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))
{
var output = new byte[entry.UnpackedSize];
UnpackTpw (input, output);
return new BinMemoryStream (output, entry.Name);
}
}
internal static void UnpackTpw (IBinaryStream input, byte[] output)
{ {
input.Position = 8; input.Position = 8;
var offsets = new int[4]; var offsets = new int[4];
@@ -250,10 +257,11 @@ namespace GameRes.Formats.Ankh
byte ctl = input.ReadUInt8(); byte ctl = input.ReadUInt8();
if (0 == ctl) if (0 == ctl)
break; break;
int remaining = output.Length - dst;
int count; int count;
if (ctl < 0x40) if (ctl < 0x40)
{ {
count = Math.Min (ctl, output.Length - dst); count = Math.Min (ctl, remaining);
input.Read (output, dst, count); input.Read (output, dst, count);
dst += count; dst += count;
} }
@@ -262,7 +270,8 @@ namespace GameRes.Formats.Ankh
if (0x6F == ctl) if (0x6F == ctl)
count = input.ReadUInt16(); count = input.ReadUInt16();
else else
count = ctl - 0x3D; count = (byte)(ctl - 0x3D);
count = Math.Min (count, remaining);
byte v = input.ReadUInt8(); byte v = input.ReadUInt8();
while (count --> 0) while (count --> 0)
output[dst++] = v; output[dst++] = v;
@@ -272,13 +281,14 @@ namespace GameRes.Formats.Ankh
if (ctl == 0x9F) if (ctl == 0x9F)
count = input.ReadUInt16(); count = input.ReadUInt16();
else else
count = ctl - 0x6E; count = (byte)(ctl - 0x6E);
byte v1 = input.ReadUInt8(); dst += input.Read (output, dst, Math.Min (2, remaining));
byte v2 = input.ReadUInt8(); --count;
while (count --> 0) if (count > 0 && remaining > 2)
{ {
output[dst++] = v1; count = Math.Min (count * 2, remaining - 2);
output[dst++] = v2; Binary.CopyOverlapped (output, dst-2, dst, count);
dst += count;
} }
} }
else if (ctl <= 0xBF) else if (ctl <= 0xBF)
@@ -286,26 +296,25 @@ namespace GameRes.Formats.Ankh
if (ctl == 0xBF) if (ctl == 0xBF)
count = input.ReadUInt16(); count = input.ReadUInt16();
else else
count = ctl - 0x9E; count = (byte)(ctl - 0x9E);
input.Read (output, dst, 3); dst += input.Read (output, dst, Math.Min (3, remaining));
if (count > 0) --count;
if (count > 0 && remaining > 3)
{ {
count *= 3; count = Math.Min (count * 3, remaining - 3);
Binary.CopyOverlapped (output, dst, dst+3, count-3); Binary.CopyOverlapped (output, dst-3, dst, count);
dst += count; dst += count;
} }
} }
else else
{ {
count = (ctl & 0x3F) + 3; count = Math.Min ((ctl & 0x3F) + 3, remaining);
int offset = input.ReadUInt8(); int offset = input.ReadUInt8();
offset = (offset & 0x3F) - offsets[offset >> 6]; offset = (offset & 0x3F) - offsets[offset >> 6];
Binary.CopyOverlapped (output, dst+offset, dst, count); Binary.CopyOverlapped (output, dst+offset, dst, count);
dst += count; dst += count;
} }
} }
return new BinMemoryStream (output, entry.Name);
}
} }
} }