mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-24 03:44:13 +08:00
(Csystem): implemented incremental images.
This commit is contained in:
parent
305680a4d3
commit
3cefd9d151
@ -174,6 +174,8 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
Extensions = new string[] { "dat", "04", "05", "06", "app" };
|
Extensions = new string[] { "dat", "04", "05", "06", "app" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool BlendOverlayImages = true;
|
||||||
|
|
||||||
static readonly ArchiveNameParser[] s_name_parsers = {
|
static readonly ArchiveNameParser[] s_name_parsers = {
|
||||||
new ArcNameParser(), new DatNameParser(), new InKyouParser()
|
new ArcNameParser(), new DatNameParser(), new InKyouParser()
|
||||||
};
|
};
|
||||||
@ -256,6 +258,7 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
var pent = entry as PackedEntry;
|
var pent = entry as PackedEntry;
|
||||||
if (null != pent && pent.IsPacked)
|
if (null != pent && pent.IsPacked)
|
||||||
{
|
{
|
||||||
|
input = new BufferedStream (input);
|
||||||
input = new LzssStream (input);
|
input = new LzssStream (input);
|
||||||
}
|
}
|
||||||
return input;
|
return input;
|
||||||
@ -269,7 +272,10 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
var input = arc.OpenBinaryEntry (entry);
|
var input = arc.OpenBinaryEntry (entry);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return DecryptImage (input, barc.Scheme);
|
var reader = DecryptImage (input, barc.Scheme);
|
||||||
|
if (BlendOverlayImages && reader is AImageReader)
|
||||||
|
reader = BlendAImage (barc, entry, reader as AImageReader);
|
||||||
|
return reader;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -301,6 +307,43 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
return new ImageFormatDecoder (input);
|
return new ImageFormatDecoder (input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IImageDecoder BlendAImage (BellArchive arc, Entry entry, AImageReader overlay)
|
||||||
|
{
|
||||||
|
var header = overlay.ReadHeader();
|
||||||
|
if (header[0] != 1)
|
||||||
|
return overlay;
|
||||||
|
var scheme = arc.Scheme;
|
||||||
|
var dir = (List<Entry>)arc.Dir;
|
||||||
|
int i = dir.IndexOf (entry);
|
||||||
|
while (--i >= 0 && "image" == dir[i].Type)
|
||||||
|
{
|
||||||
|
using (var input = OpenEntry (arc, dir[i]))
|
||||||
|
{
|
||||||
|
int type = input.ReadByte();
|
||||||
|
if (type != 'a')
|
||||||
|
break;
|
||||||
|
int id = input.ReadByte();
|
||||||
|
if (id != scheme.Value2)
|
||||||
|
break;
|
||||||
|
using (var bin = new BinaryStream (input, dir[i].Name))
|
||||||
|
using (var base_image = new AImageReader (bin, scheme))
|
||||||
|
{
|
||||||
|
var base_header = base_image.ReadHeader();
|
||||||
|
if (1 == base_header[0])
|
||||||
|
continue;
|
||||||
|
// check if image width/height are the same
|
||||||
|
if (base_header[3] == header[3] && base_header[4] == header[4])
|
||||||
|
{
|
||||||
|
base_image.Unpack();
|
||||||
|
overlay.Baseline = base_image.Data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
|
||||||
internal AImageScheme QueryScheme (string arc_name)
|
internal AImageScheme QueryScheme (string arc_name)
|
||||||
{
|
{
|
||||||
var title = FormatCatalog.Instance.LookupGame (arc_name);
|
var title = FormatCatalog.Instance.LookupGame (arc_name);
|
||||||
@ -579,9 +622,8 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
var entry = ReadEntryInfo();
|
var entry = ReadEntryInfo();
|
||||||
if (ReadEntryType (entry, entry_size))
|
if (ReadEntryType (entry, entry_size))
|
||||||
{
|
{
|
||||||
if (!entry.CheckPlacement (MaxOffset))
|
if (entry.CheckPlacement (MaxOffset))
|
||||||
return false;
|
m_dir.Add (entry);
|
||||||
m_dir.Add (entry);
|
|
||||||
}
|
}
|
||||||
m_index.Position = next_pos;
|
m_index.Position = next_pos;
|
||||||
}
|
}
|
||||||
@ -668,6 +710,8 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
|
|
||||||
protected override bool ReadEntryType (Entry entry, int entry_size)
|
protected override bool ReadEntryType (Entry entry, int entry_size)
|
||||||
{
|
{
|
||||||
|
if (entry_size > 0x11)
|
||||||
|
throw new InvalidFormatException();
|
||||||
char type = (char)m_index.ReadByte();
|
char type = (char)m_index.ReadByte();
|
||||||
if (type > 0x20 && type < 0x7F)
|
if (type > 0x20 && type < 0x7F)
|
||||||
{
|
{
|
||||||
|
@ -51,10 +51,12 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
byte[] m_output;
|
byte[] m_output;
|
||||||
AImageScheme m_scheme;
|
AImageScheme m_scheme;
|
||||||
ImageData m_image;
|
ImageData m_image;
|
||||||
|
int[] m_header;
|
||||||
|
|
||||||
public Stream Source { get { m_input.Position = 0; return m_input.AsStream; } }
|
public Stream Source { get { m_input.Position = 0; return m_input.AsStream; } }
|
||||||
public ImageFormat SourceFormat { get { return null; } }
|
public ImageFormat SourceFormat { get { return null; } }
|
||||||
public ImageMetaData Info { get { return m_info; } }
|
public ImageMetaData Info { get { return m_info; } }
|
||||||
|
public byte[] Baseline { get; set; }
|
||||||
|
|
||||||
public ImageData Image
|
public ImageData Image
|
||||||
{
|
{
|
||||||
@ -81,17 +83,25 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
m_scheme = scheme;
|
m_scheme = scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unpack ()
|
internal int[] ReadHeader ()
|
||||||
{
|
{
|
||||||
|
if (m_header != null)
|
||||||
|
return m_header;
|
||||||
int header_length = Math.Max (8, m_scheme.HeaderOrder.Length);
|
int header_length = Math.Max (8, m_scheme.HeaderOrder.Length);
|
||||||
var header = new int[header_length];
|
m_header = new int[header_length];
|
||||||
for (int i = 0; i < m_scheme.HeaderOrder.Length; ++i)
|
for (int i = 0; i < m_scheme.HeaderOrder.Length; ++i)
|
||||||
{
|
{
|
||||||
int b = GetInt();
|
int b = GetInt();
|
||||||
header[m_scheme.HeaderOrder[i]] = b;
|
m_header[m_scheme.HeaderOrder[i]] = b;
|
||||||
}
|
}
|
||||||
Info.Width = (uint)header[4];
|
Info.Width = (uint)m_header[4];
|
||||||
Info.Height = (uint)header[3];
|
Info.Height = (uint)m_header[3];
|
||||||
|
return m_header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unpack ()
|
||||||
|
{
|
||||||
|
var header = ReadHeader();
|
||||||
if (0 == Info.Width || Info.Width >= 0x8000 || 0 == Info.Height || Info.Height >= 0x8000)
|
if (0 == Info.Width || Info.Width >= 0x8000 || 0 == Info.Height || Info.Height >= 0x8000)
|
||||||
throw new InvalidFormatException();
|
throw new InvalidFormatException();
|
||||||
int unpacked_size = header[5];
|
int unpacked_size = header[5];
|
||||||
@ -160,22 +170,32 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
if (alpha_map.Length != alpha_size)
|
if (alpha_map.Length != alpha_size)
|
||||||
throw new InvalidFormatException();
|
throw new InvalidFormatException();
|
||||||
|
|
||||||
Info.BPP = 32;
|
|
||||||
int plane_size = (int)Info.Width * (int)Info.Height;
|
int plane_size = (int)Info.Width * (int)Info.Height;
|
||||||
m_output = new byte[plane_size * 4];
|
if (Baseline != null)
|
||||||
|
{
|
||||||
|
Info.BPP = 24;
|
||||||
|
m_output = Baseline;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info.BPP = 32;
|
||||||
|
m_output = new byte[plane_size * 4];
|
||||||
|
}
|
||||||
|
int pixel_size = Info.BPP / 8;
|
||||||
int bit = 1;
|
int bit = 1;
|
||||||
int bit_src = 0;
|
int bit_src = 0;
|
||||||
int dst = 0;
|
int dst = 0;
|
||||||
for (int i = 0; i < plane_size; ++i)
|
for (int i = 0; i < plane_size; ++i)
|
||||||
{
|
{
|
||||||
|
byte alpha = 0;
|
||||||
if ((bit & alpha_map[bit_src]) != 0)
|
if ((bit & alpha_map[bit_src]) != 0)
|
||||||
{
|
{
|
||||||
m_input.Read (m_output, dst, 3);
|
m_input.Read (m_output, dst, 3);
|
||||||
m_output[dst+3] = 0xFF;
|
alpha = 0xFF;
|
||||||
}
|
}
|
||||||
else
|
if (4 == pixel_size)
|
||||||
m_output[dst+3] = 0;
|
m_output[dst+3] = alpha;
|
||||||
dst += 4;
|
dst += pixel_size;
|
||||||
if (0x80 == bit)
|
if (0x80 == bit)
|
||||||
{
|
{
|
||||||
++bit_src;
|
++bit_src;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user