mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-27 07:34:00 +08:00
(RCT): limit recursion when reading baseline images.
This commit is contained in:
parent
884c7acc85
commit
186444f957
@ -45,7 +45,8 @@ namespace GameRes.Formats.Majiro
|
|||||||
public bool IsEncrypted;
|
public bool IsEncrypted;
|
||||||
public uint DataOffset;
|
public uint DataOffset;
|
||||||
public int DataSize;
|
public int DataSize;
|
||||||
public int AddSize;
|
public int BaseNameLength;
|
||||||
|
public int BaseRecursionDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class RctOptions : ResourceOptions
|
internal class RctOptions : ResourceOptions
|
||||||
@ -69,6 +70,7 @@ namespace GameRes.Formats.Majiro
|
|||||||
|
|
||||||
public bool OverlayFrames = true;
|
public bool OverlayFrames = true;
|
||||||
public bool ApplyMask = true;
|
public bool ApplyMask = true;
|
||||||
|
public const int BaseRecursionLimit = 8;
|
||||||
|
|
||||||
public static Dictionary<string, string> KnownKeys = new Dictionary<string, string>();
|
public static Dictionary<string, string> KnownKeys = new Dictionary<string, string>();
|
||||||
|
|
||||||
@ -117,7 +119,7 @@ namespace GameRes.Formats.Majiro
|
|||||||
IsEncrypted = is_encrypted,
|
IsEncrypted = is_encrypted,
|
||||||
DataOffset = (uint)stream.Position,
|
DataOffset = (uint)stream.Position,
|
||||||
DataSize = data_size,
|
DataSize = data_size,
|
||||||
AddSize = additional_size,
|
BaseNameLength = additional_size,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,15 +128,7 @@ namespace GameRes.Formats.Majiro
|
|||||||
public override ImageData Read (IBinaryStream file, ImageMetaData info)
|
public override ImageData Read (IBinaryStream file, ImageMetaData info)
|
||||||
{
|
{
|
||||||
var meta = (RctMetaData)info;
|
var meta = (RctMetaData)info;
|
||||||
|
|
||||||
byte[] base_image = null;
|
|
||||||
if (meta.FileName != null && meta.AddSize > 0 && OverlayFrames)
|
|
||||||
base_image = ReadBaseImage (file, meta);
|
|
||||||
|
|
||||||
var pixels = ReadPixelsData (file, meta);
|
var pixels = ReadPixelsData (file, meta);
|
||||||
if (base_image != null)
|
|
||||||
pixels = CombineImage (base_image, pixels);
|
|
||||||
|
|
||||||
if (ApplyMask)
|
if (ApplyMask)
|
||||||
{
|
{
|
||||||
var base_name = Path.GetFileNameWithoutExtension (meta.FileName);
|
var base_name = Path.GetFileNameWithoutExtension (meta.FileName);
|
||||||
@ -201,7 +195,12 @@ namespace GameRes.Formats.Majiro
|
|||||||
|
|
||||||
byte[] ReadPixelsData (IBinaryStream file, RctMetaData meta)
|
byte[] ReadPixelsData (IBinaryStream file, RctMetaData meta)
|
||||||
{
|
{
|
||||||
file.Position = meta.DataOffset + meta.AddSize;
|
byte[] base_image = null;
|
||||||
|
if (meta.FileName != null && meta.BaseNameLength > 0 && OverlayFrames
|
||||||
|
&& meta.BaseRecursionDepth < BaseRecursionLimit)
|
||||||
|
base_image = ReadBaseImage (file, meta);
|
||||||
|
|
||||||
|
file.Position = meta.DataOffset + meta.BaseNameLength;
|
||||||
if (meta.IsEncrypted)
|
if (meta.IsEncrypted)
|
||||||
file = OpenEncryptedStream (file, meta.DataSize);
|
file = OpenEncryptedStream (file, meta.DataSize);
|
||||||
try
|
try
|
||||||
@ -209,6 +208,8 @@ namespace GameRes.Formats.Majiro
|
|||||||
using (var reader = new Reader (file, meta))
|
using (var reader = new Reader (file, meta))
|
||||||
{
|
{
|
||||||
reader.Unpack();
|
reader.Unpack();
|
||||||
|
if (base_image != null)
|
||||||
|
return CombineImage (base_image, reader.Data);
|
||||||
return reader.Data;
|
return reader.Data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,13 +223,10 @@ namespace GameRes.Formats.Majiro
|
|||||||
|
|
||||||
byte[] ReadBaseImage (IBinaryStream file, RctMetaData meta)
|
byte[] ReadBaseImage (IBinaryStream file, RctMetaData meta)
|
||||||
{
|
{
|
||||||
file.Position = meta.DataOffset;
|
|
||||||
byte[] name_bin = file.ReadBytes (meta.AddSize);
|
|
||||||
if (name_bin.Length != meta.AddSize)
|
|
||||||
throw new EndOfStreamException();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string name = Encodings.cp932.GetString (name_bin, 0, name_bin.Length-1);
|
file.Position = meta.DataOffset;
|
||||||
|
var name = file.ReadCString (meta.BaseNameLength);
|
||||||
string dir_name = VFS.GetDirectoryName (meta.FileName);
|
string dir_name = VFS.GetDirectoryName (meta.FileName);
|
||||||
name = VFS.CombinePath (dir_name, name);
|
name = VFS.CombinePath (dir_name, name);
|
||||||
if (VFS.FileExists (name))
|
if (VFS.FileExists (name))
|
||||||
@ -236,9 +234,10 @@ namespace GameRes.Formats.Majiro
|
|||||||
using (var base_file = VFS.OpenBinaryStream (name))
|
using (var base_file = VFS.OpenBinaryStream (name))
|
||||||
{
|
{
|
||||||
var base_info = ReadMetaData (base_file) as RctMetaData;
|
var base_info = ReadMetaData (base_file) as RctMetaData;
|
||||||
if (null != base_info && 0 == base_info.AddSize
|
if (null != base_info
|
||||||
&& meta.Width == base_info.Width && meta.Height == base_info.Height)
|
&& meta.Width == base_info.Width && meta.Height == base_info.Height)
|
||||||
{
|
{
|
||||||
|
base_info.BaseRecursionDepth = meta.BaseRecursionDepth + 1;
|
||||||
base_info.FileName = name;
|
base_info.FileName = name;
|
||||||
return ReadPixelsData (base_file, base_info);
|
return ReadPixelsData (base_file, base_info);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user