mirror of
https://github.com/lifegpc/GARbro.git
synced 2026-07-08 01:31:41 +08:00
(AImageReader): implemented IImageDecoder interface.
This commit is contained in:
@@ -194,20 +194,24 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
|
|
||||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
{
|
{
|
||||||
uint entry_size = entry.Size;
|
Stream input = arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
Stream input = arc.File.CreateStream (entry.Offset, entry_size);
|
|
||||||
var pent = entry as PackedEntry;
|
var pent = entry as PackedEntry;
|
||||||
if (null != pent && pent.IsPacked)
|
if (null != pent && pent.IsPacked)
|
||||||
{
|
{
|
||||||
input = new LzssStream (input);
|
input = new LzssStream (input);
|
||||||
entry_size = pent.UnpackedSize;
|
|
||||||
}
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IImageDecoder OpenImage (ArcFile arc, Entry entry)
|
||||||
|
{
|
||||||
var barc = arc as BellArchive;
|
var barc = arc as BellArchive;
|
||||||
if (null == barc || entry.Type != "image" || entry_size < 5)
|
if (null == barc || entry.Size < 5)
|
||||||
return input;
|
return base.OpenImage (arc, entry);
|
||||||
|
var input = arc.OpenBinaryEntry (entry);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return DecryptImage (input, entry_size, barc.Scheme);
|
return DecryptImage (input, barc.Scheme);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -216,47 +220,27 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Stream DecryptImage (Stream input, uint entry_size, AImageScheme scheme)
|
protected virtual IImageDecoder DecryptImage (IBinaryStream input, AImageScheme scheme)
|
||||||
{
|
{
|
||||||
byte[] header = null;
|
int type = input.ReadByte();
|
||||||
byte type = (byte)input.ReadByte();
|
|
||||||
if ('c' == type || 'b' == type)
|
if ('c' == type || 'b' == type)
|
||||||
{
|
{
|
||||||
header = new byte[5];
|
uint img_size = Binary.BigEndian (input.ReadUInt32());
|
||||||
header[0] = type;
|
if (input.Length - 5 == img_size)
|
||||||
input.Read (header, 1, 4);
|
|
||||||
uint img_size = BigEndian.ToUInt32 (header, 1);
|
|
||||||
if (entry_size - 5 == img_size)
|
|
||||||
{
|
{
|
||||||
if (input.CanSeek)
|
input = BinaryStream.FromStream (new StreamRegion (input.AsStream, 5, img_size), input.Name);
|
||||||
input = new StreamRegion (input, 5, img_size);
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (scheme != null && 'a' == type && entry_size > 21)
|
else if (scheme != null && 'a' == type && input.Length > 21)
|
||||||
{
|
{
|
||||||
int id = input.ReadByte();
|
int id = input.ReadByte();
|
||||||
if (id == scheme.Value2)
|
if (id == scheme.Value2)
|
||||||
{
|
{
|
||||||
using (var reader = new AImageReader (input, scheme))
|
return new AImageReader (input, scheme);
|
||||||
{
|
|
||||||
reader.Unpack();
|
|
||||||
return TgaStream.Create (reader.Info, reader.Data, scheme.Flipped);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
header = new byte[2] { type, (byte)id };
|
|
||||||
}
|
}
|
||||||
if (input.CanSeek)
|
input.Position = 0;
|
||||||
{
|
return new ImageStreamDecoder (input);
|
||||||
input.Position = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (null == header)
|
|
||||||
header = new byte[1] { type };
|
|
||||||
input = new PrefixStream (header, input);
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint DecodeDecimal (ArcView file, long offset)
|
uint DecodeDecimal (ArcView file, long offset)
|
||||||
@@ -419,27 +403,13 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
return new BellArchive (file, this, dir, scheme);
|
return new BellArchive (file, this, dir, scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Stream DecryptImage (Stream input, uint entry_size, AImageScheme scheme)
|
protected override IImageDecoder DecryptImage (IBinaryStream input, AImageScheme scheme)
|
||||||
{
|
{
|
||||||
int id = input.ReadByte();
|
int id = input.ReadByte();
|
||||||
if (id == scheme.Value2)
|
if (id == scheme.Value2)
|
||||||
{
|
return new AImageReader (input, scheme);
|
||||||
using (var reader = new AImageReader (input, scheme))
|
input.Position = 0;
|
||||||
{
|
return new ImageStreamDecoder (input);
|
||||||
reader.Unpack();
|
|
||||||
return TgaStream.Create (reader.Info, reader.Data, scheme.Flipped);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (input.CanSeek)
|
|
||||||
{
|
|
||||||
input.Position = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var header = new byte[1] { (byte)id };
|
|
||||||
input = new PrefixStream (header, input);
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] ReadToc (string toc_name)
|
byte[] ReadToc (string toc_name)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace GameRes.Formats.Cyberworks
|
namespace GameRes.Formats.Cyberworks
|
||||||
{
|
{
|
||||||
@@ -42,19 +43,41 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
Ignored = Field1,
|
Ignored = Field1,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class AImageReader : IDisposable
|
internal sealed class AImageReader : IImageDecoder
|
||||||
{
|
{
|
||||||
public readonly ImageMetaData Info = new ImageMetaData();
|
readonly ImageMetaData m_info = new ImageMetaData();
|
||||||
|
|
||||||
BinaryReader m_input;
|
IBinaryStream m_input;
|
||||||
byte[] m_output;
|
byte[] m_output;
|
||||||
AImageScheme m_scheme;
|
AImageScheme m_scheme;
|
||||||
|
ImageData m_image;
|
||||||
|
|
||||||
|
public Stream Input { get { m_input.Position = 0; return m_input.AsStream; } }
|
||||||
|
public ImageMetaData Info { get { return m_info; } }
|
||||||
|
public ImageFormat Format { get { return null; } }
|
||||||
|
|
||||||
|
public ImageData Image
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (null == m_image)
|
||||||
|
{
|
||||||
|
Unpack();
|
||||||
|
int stride = (int)Info.Width * Info.BPP / 8;
|
||||||
|
if (m_scheme.Flipped)
|
||||||
|
m_image = ImageData.CreateFlipped (Info, GetPixelFormat(), null, Data, stride);
|
||||||
|
else
|
||||||
|
m_image = ImageData.Create (Info, GetPixelFormat(), null, Data, stride);
|
||||||
|
}
|
||||||
|
return m_image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] Data { get { return m_output; } }
|
public byte[] Data { get { return m_output; } }
|
||||||
|
|
||||||
public AImageReader (Stream input, AImageScheme scheme)
|
public AImageReader (IBinaryStream input, AImageScheme scheme)
|
||||||
{
|
{
|
||||||
m_input = new ArcView.Reader (input);
|
m_input = input;
|
||||||
m_scheme = scheme;
|
m_scheme = scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,14 +254,14 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
|
|
||||||
int GetInt ()
|
int GetInt ()
|
||||||
{
|
{
|
||||||
byte a = m_input.ReadByte();
|
byte a = m_input.ReadUInt8();
|
||||||
if (a == m_scheme.Value3)
|
if (a == m_scheme.Value3)
|
||||||
a = 0;
|
a = 0;
|
||||||
int d = 0;
|
int d = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
byte a1 = m_input.ReadByte();
|
byte a1 = m_input.ReadUInt8();
|
||||||
if (a1 == m_scheme.Value2)
|
if (a1 == m_scheme.Value2)
|
||||||
break;
|
break;
|
||||||
if (a1 != m_scheme.Value1)
|
if (a1 != m_scheme.Value1)
|
||||||
@@ -253,6 +276,17 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
return a + (c + d * m_scheme.Value1) * m_scheme.Value1;
|
return a + (c + d * m_scheme.Value1) * m_scheme.Value1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PixelFormat GetPixelFormat ()
|
||||||
|
{
|
||||||
|
switch (Info.BPP)
|
||||||
|
{
|
||||||
|
case 8: return PixelFormats.Gray8;
|
||||||
|
case 24: return PixelFormats.Bgr24;
|
||||||
|
case 32: return PixelFormats.Bgra32;
|
||||||
|
default: throw new InvalidFormatException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region IDisposable Members
|
#region IDisposable Members
|
||||||
bool _disposed = false;
|
bool _disposed = false;
|
||||||
public void Dispose ()
|
public void Dispose ()
|
||||||
|
|||||||
Reference in New Issue
Block a user