(PX): additional formats.

This commit is contained in:
morkt
2017-03-24 22:45:43 +04:00
parent 0d98917d5e
commit 5620f48ea9
2 changed files with 330 additions and 11 deletions

View File

@@ -30,6 +30,11 @@ using GameRes.Compression;
namespace GameRes.Formats.Leaf
{
internal class ALeafEntry : PackedEntry
{
public byte Key;
}
[Export(typeof(ArchiveFormat))]
public class AOpener : ArchiveFormat
{
@@ -60,8 +65,9 @@ namespace GameRes.Formats.Leaf
var name = file.View.ReadString (index_offset, 0x17);
if (string.IsNullOrEmpty (name))
return null;
var entry = FormatCatalog.Instance.Create<PackedEntry> (name);
entry.IsPacked = 0 != file.View.ReadByte (index_offset+0x17);
var entry = FormatCatalog.Instance.Create<ALeafEntry> (name);
entry.Key = file.View.ReadByte (index_offset+0x17);
entry.IsPacked = 0 != entry.Key;
entry.Size = file.View.ReadUInt32 (index_offset+0x18);
entry.Offset = base_offset + file.View.ReadUInt32 (index_offset+0x1C);
if (!entry.CheckPlacement (file.MaxOffset))
@@ -74,13 +80,47 @@ namespace GameRes.Formats.Leaf
public override Stream OpenEntry (ArcFile arc, Entry entry)
{
var pent = entry as PackedEntry;
var pent = entry as ALeafEntry;
if (null == pent || !pent.IsPacked)
return base.OpenEntry (arc, entry);
if (0 == pent.UnpackedSize)
pent.UnpackedSize = arc.File.View.ReadUInt32 (entry.Offset);
var input = arc.File.CreateStream (entry.Offset+4, entry.Size-4);
return new LzssStream (input);
Stream input = arc.File.CreateStream (entry.Offset+4, entry.Size-4);
input = new LzssStream (input);
if (pent.Key >= 0x7F && pent.Key <= 0x89 && pent.UnpackedSize > 0x20)
{
using (input)
return Decrypt (input, pent.UnpackedSize, (byte)(pent.Key & 0xF));
}
return input;
}
Stream Decrypt (Stream input, uint length, byte key)
{
var data = new byte[length];
input.Read (data, 0, data.Length);
uint width = data.ToUInt32 (0);
uint height = data.ToUInt32 (4);
uint image_size = width * height;
int type = data.ToUInt16 (0x10);
int bits = data.ToUInt16 (0x12);
if (1 == type && 0x20 == bits && image_size > 0 && (32 + image_size * 4) <= length)
{
byte r = 0, g = 0, b = 0;
int dst = 0x20;
for (uint i = 0; i < image_size; ++i)
{
byte a = data[dst+3];
b += (byte)(data[dst ] + a - key);
g += (byte)(data[dst+1] + a - key);
r += (byte)(data[dst+2] + a - key);
data[dst++] = b;
data[dst++] = g;
data[dst++] = r;
data[dst++] = 0;
}
}
return new BinMemoryStream (data);
}
}
}