IBinaryStream migration - continued.

This commit is contained in:
morkt 2016-10-15 12:21:12 +04:00
parent 503b734645
commit d0c1d5da01
39 changed files with 529 additions and 574 deletions

View File

@ -52,18 +52,18 @@ namespace GameRes.Formats.Abel
Extensions = new string[] { "gps", "cmp" };
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x29];
if (header.Length != stream.Read (header, 0, header.Length))
var header = stream.ReadHeader (0x29);
if (header.Length != 0x29)
return null;
var gps = new GpsMetaData
{
Width = LittleEndian.ToUInt32 (header, 0x19),
Height = LittleEndian.ToUInt32 (header, 0x1D),
Width = header.ToUInt32 (0x19),
Height = header.ToUInt32 (0x1D),
Compression = header[0x10],
UnpackedSize = LittleEndian.ToInt32 (header, 0x11),
PackedSize = LittleEndian.ToInt32 (header, 0x15),
UnpackedSize = header.ToInt32 (0x11),
PackedSize = header.ToInt32 (0x15),
};
// read BMP header
using (var input = OpenGpsStream (stream, gps.Compression, 0x54))
@ -76,7 +76,7 @@ namespace GameRes.Formats.Abel
}
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var gps = (GpsMetaData)info;
stream.Position = 0x29;
@ -89,21 +89,23 @@ namespace GameRes.Formats.Abel
throw new System.NotImplementedException ("GpsFormat.Write not implemented");
}
Stream OpenGpsStream (Stream input, byte compression, int unpacked_size)
IBinaryStream OpenGpsStream (IBinaryStream input, byte compression, int unpacked_size)
{
Stream gps = null;
if (0 == compression)
return new StreamRegion (input, 0x29, true);
gps = new StreamRegion (input.AsStream, 0x29, true);
else if (1 == compression)
return OpenRLEStream (input, unpacked_size);
gps = OpenRLEStream (input.AsStream, unpacked_size);
else if (2 == compression)
return new LzssStream (input, LzssMode.Decompress, true);
gps = new LzssStream (input.AsStream, LzssMode.Decompress, true);
else if (3 == compression)
{
using (var lzss = new LzssStream (input, LzssMode.Decompress, true))
return OpenRLEStream (lzss, unpacked_size);
using (var lzss = new LzssStream (input.AsStream, LzssMode.Decompress, true))
gps = OpenRLEStream (lzss, unpacked_size);
}
else
throw new InvalidFormatException();
return new BinaryStream (gps);
}
Stream OpenRLEStream (Stream input, int output_size)

View File

@ -43,10 +43,10 @@ namespace GameRes.Formats.AdvSys
public override string Description { get { return "AdvSys3 engine image format"; } }
public override uint Signature { get { return 0; } }
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[12];
if (header.Length != stream.Read (header, 0, header.Length))
var header = stream.ReadHeader (12);
if (header.Length != 12)
return null;
if (!Binary.AsciiEqual (header, 4, "GWD"))
return null;
@ -59,7 +59,7 @@ namespace GameRes.Formats.AdvSys
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
PixelFormat format = 24 == info.BPP ? PixelFormats.Bgr24 : PixelFormats.Gray8;
byte[] image;
@ -71,7 +71,8 @@ namespace GameRes.Formats.AdvSys
stream.Position = 4 + meta.DataSize;
if (24 == info.BPP && 1 == stream.ReadByte())
{
using (var alpha_stream = new StreamRegion (stream, stream.Position, true))
using (var part = new StreamRegion (stream.AsStream, stream.Position, true))
using (var alpha_stream = new BinaryStream (part))
{
var alpha_info = ReadMetaData (alpha_stream) as GwdMetaData;
if (null != alpha_info && 8 == alpha_info.BPP
@ -120,13 +121,13 @@ namespace GameRes.Formats.AdvSys
public byte[] Pixels { get { return m_output; } }
public int InputSize { get; private set; }
public GwdReader (Stream input, ImageMetaData info)
public GwdReader (IBinaryStream input, ImageMetaData info)
{
m_bpp = info.BPP;
if (m_bpp != 8 && m_bpp != 24)
throw new InvalidFormatException();
m_input = new MsbBitStream (input, true);
m_input = new MsbBitStream (input.AsStream, true);
m_width = (int)info.Width;
m_height = (int)info.Height;
m_stride = m_width * m_bpp / 8;

View File

@ -50,7 +50,7 @@ namespace GameRes.Formats.AliceSoft
0x5D, 0x91, 0xAE, 0x87, 0x4A, 0x56, 0x41, 0xCD, 0x83, 0xEC, 0x4C, 0x92, 0xB5, 0xCB, 0x16, 0x34
};
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x18];
stream.Position = 0xC;
@ -68,12 +68,12 @@ namespace GameRes.Formats.AliceSoft
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (AjpMetaData)info;
int stride = (int)meta.Width * 4;
byte[] pixels;
using (var jpeg = DecryptStream (stream, meta.ImageOffset, meta.ImageSize))
using (var jpeg = DecryptStream (stream.AsStream, meta.ImageOffset, meta.ImageSize))
{
var decoder = new JpegBitmapDecoder (jpeg,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
@ -84,7 +84,7 @@ namespace GameRes.Formats.AliceSoft
pixels = new byte[stride * (int)meta.Height];
bitmap.CopyPixels (pixels, stride, 0);
}
using (var mask = DecryptStream (stream, meta.AlphaOffset, meta.AlphaSize))
using (var mask = DecryptStream (stream.AsStream, meta.AlphaOffset, meta.AlphaSize))
{
var alpha = ReadMask (mask);
int src = 0;

View File

@ -46,39 +46,36 @@ namespace GameRes.Formats.AliceSoft
public override string Description { get { return "AliceSoft System incremental image"; } }
public override uint Signature { get { return 0x20666364; } } // 'dcf '
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
using (var reader = new ArcView.Reader (stream))
stream.Seek (4, SeekOrigin.Current);
uint header_size = stream.ReadUInt32();
long data_pos = stream.Position + header_size;
if (stream.ReadInt32() != 1)
return null;
uint width = stream.ReadUInt32();
uint height = stream.ReadUInt32();
int bpp = stream.ReadInt32();
int name_length = stream.ReadInt32();
if (name_length <= 0)
return null;
int shift = (name_length % 7) + 1;
var name_bits = stream.ReadBytes (name_length);
for (int i = 0; i < name_length; ++i)
{
stream.Seek (4, SeekOrigin.Current);
uint header_size = reader.ReadUInt32();
long data_pos = stream.Position + header_size;
if (reader.ReadInt32() != 1)
return null;
uint width = reader.ReadUInt32();
uint height = reader.ReadUInt32();
int bpp = reader.ReadInt32();
int name_length = reader.ReadInt32();
if (name_length <= 0)
return null;
int shift = (name_length % 7) + 1;
var name_bits = reader.ReadBytes (name_length);
for (int i = 0; i < name_length; ++i)
{
name_bits[i] = Binary.RotByteL (name_bits[i], shift);
}
return new DcfMetaData
{
Width = width,
Height = height,
BPP = bpp,
BaseName = Encodings.cp932.GetString (name_bits),
DataOffset = data_pos,
};
name_bits[i] = Binary.RotByteL (name_bits[i], shift);
}
return new DcfMetaData
{
Width = width,
Height = height,
BPP = bpp,
BaseName = Encodings.cp932.GetString (name_bits),
DataOffset = data_pos,
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
using (var reader = new DcfReader (stream, (DcfMetaData)info))
{
@ -93,9 +90,9 @@ namespace GameRes.Formats.AliceSoft
}
}
internal class DcfReader : IDisposable
internal sealed class DcfReader : IDisposable
{
BinaryReader m_input;
IBinaryStream m_input;
DcfMetaData m_info;
byte[] m_output;
byte[] m_mask = null;
@ -111,9 +108,9 @@ namespace GameRes.Formats.AliceSoft
public PixelFormat Format { get; private set; }
public int Stride { get; private set; }
public DcfReader (Stream input, DcfMetaData info)
public DcfReader (IBinaryStream input, DcfMetaData info)
{
m_input = new ArcView.Reader (input);
m_input = input;
m_info = info;
}
@ -122,7 +119,7 @@ namespace GameRes.Formats.AliceSoft
long next_pos = m_info.DataOffset;
for (;;)
{
m_input.BaseStream.Position = next_pos;
m_input.Position = next_pos;
uint id = m_input.ReadUInt32();
next_pos += 8 + m_input.ReadUInt32();
if (0x6C646664 == id) // 'dfdl'
@ -131,22 +128,22 @@ namespace GameRes.Formats.AliceSoft
if (unpacked_size <= 0)
continue;
m_mask = new byte[unpacked_size];
using (var input = new ZLibStream (m_input.BaseStream, CompressionMode.Decompress, true))
using (var input = new ZLibStream (m_input.AsStream, CompressionMode.Decompress, true))
input.Read (m_mask, 0, unpacked_size);
}
else if (0x64676364 == id) // 'dcgd'
break;
}
long qnt_pos = m_input.BaseStream.Position;
long qnt_pos = m_input.Position;
if (m_input.ReadUInt32() != Qnt.Signature)
throw new InvalidFormatException();
m_input.BaseStream.Seek (-4, SeekOrigin.Current);
var qnt_info = Qnt.ReadMetaData (m_input.BaseStream) as QntMetaData;
m_input.Seek (-4, SeekOrigin.Current);
var qnt_info = Qnt.ReadMetaData (m_input) as QntMetaData;
if (null == qnt_info)
throw new InvalidFormatException();
m_input.BaseStream.Position = qnt_pos + 0x44;
var overlay = new QntFormat.Reader (m_input.BaseStream, qnt_info);
m_input.Position = qnt_pos + 0x44;
var overlay = new QntFormat.Reader (m_input, qnt_info);
overlay.Unpack();
m_overlay_bpp = overlay.BPP;
if (m_mask != null)
@ -236,14 +233,8 @@ namespace GameRes.Formats.AliceSoft
}
#region IDisposable Members
bool _disposed = false;
public void Dispose ()
{
if (!_disposed)
{
m_input.Dispose();
_disposed = true;
}
}
#endregion
}

View File

@ -42,28 +42,26 @@ namespace GameRes.Formats.Ice
Signatures = new uint[] { 0x010001, 0x020001 };
}
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
var header = new byte[0x16];
if (header.Length != file.Read (header, 0, header.Length))
return null;
ushort tag = LittleEndian.ToUInt16 (header, 0);
var header = file.ReadHeader (0x16);
ushort tag = header.ToUInt16 (0);
if (tag != 1)
return null;
int extra_size = LittleEndian.ToUInt16 (header, 0x10);
int extra_size = header.ToUInt16 (0x10);
if (0 != extra_size)
return null;
uint pcm_size = LittleEndian.ToUInt32 (header, 0x12);
uint pcm_size = header.ToUInt32 (0x12);
if (pcm_size + 0x16 != file.Length)
return null;
var format = new WaveFormat { FormatTag = tag };
format.Channels = LittleEndian.ToUInt16 (header, 2);
format.Channels = header.ToUInt16 (2);
if (format.Channels != 1 && format.Channels != 2)
return null;
format.SamplesPerSecond = LittleEndian.ToUInt32 (header, 4);
format.AverageBytesPerSecond = LittleEndian.ToUInt32 (header, 8);
format.BlockAlign = LittleEndian.ToUInt16 (header, 0xC);
format.BitsPerSample = LittleEndian.ToUInt16 (header, 0xE);
format.SamplesPerSecond = header.ToUInt32 (4);
format.AverageBytesPerSecond = header.ToUInt32 (8);
format.BlockAlign = header.ToUInt16 (0xC);
format.BitsPerSample = header.ToUInt16 (0xE);
if (0 == format.AverageBytesPerSecond
|| format.SamplesPerSecond * format.BlockAlign != format.AverageBytesPerSecond)
return null;

View File

@ -54,120 +54,118 @@ namespace GameRes.Formats.Aoi
Extensions = new string[] { "agf" };
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x80];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
int version = LittleEndian.ToInt32 (header, 4);
var header = stream.ReadHeader (0x80);
int version = header.ToInt32 (4);
if (version != 1 && version != 2)
return null;
var info = new AgfMetaData
{
Width = LittleEndian.ToUInt32 (header, 0x1C),
Height = LittleEndian.ToUInt32 (header, 0x20),
Width = header.ToUInt32 (0x1C),
Height = header.ToUInt32 (0x20),
BPP = 32,
Version = version,
};
if (1 == version)
{
info.DataOffset = LittleEndian.ToUInt32 (header, 0x0C);
info.DataOffset = header.ToUInt32 (0x0C);
}
else
{
info.DataOffset = LittleEndian.ToUInt32 (header, 0x10);
info.Flags = LittleEndian.ToUInt32 (header, 0x54);
info.BaseNameOffset = LittleEndian.ToUInt32 (header, 0x6C);
info.DataOffset = header.ToUInt32 (0x10);
info.Flags = header.ToUInt32 (0x54);
info.BaseNameOffset = header.ToUInt32 (0x6C);
}
return info;
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream input, ImageMetaData info)
{
var meta = (AgfMetaData)info;
var pixels = new byte[meta.Width * meta.Height * 4];
int dst = 0;
stream.Position = meta.DataOffset;
using (var input = new BinaryReader (stream, Encoding.Unicode, true))
input.Position = meta.DataOffset;
while (dst < pixels.Length)
{
while (dst < pixels.Length)
uint op = input.ReadUInt32();
int count = (int)(op >> 8);
switch (op & 0xFF)
{
uint op = input.ReadUInt32();
int count = (int)(op >> 8);
switch (op & 0xFF)
{
case 1:
count *= 4;
input.Read (pixels, dst, count);
break;
case 1:
count *= 4;
input.Read (pixels, dst, count);
break;
case 2:
input.Read (pixels, dst, 4);
count *= 4;
Binary.CopyOverlapped (pixels, dst, dst+4, count - 4);
break;
case 2:
input.Read (pixels, dst, 4);
count *= 4;
Binary.CopyOverlapped (pixels, dst, dst+4, count - 4);
break;
case 3:
int chunk_size = (count >> 8) * 4;
count = (count & 0xFF) * chunk_size;
input.Read (pixels, dst, chunk_size);
Binary.CopyOverlapped (pixels, dst, dst + chunk_size, count - chunk_size);
break;
case 3:
int chunk_size = (count >> 8) * 4;
count = (count & 0xFF) * chunk_size;
input.Read (pixels, dst, chunk_size);
Binary.CopyOverlapped (pixels, dst, dst + chunk_size, count - chunk_size);
break;
case 4:
int offset = (count & 0xFFF) * 4;
count = (count >> 12) * 4;
Binary.CopyOverlapped (pixels, dst - offset, dst, count);
break;
case 4:
int offset = (count & 0xFFF) * 4;
count = (count >> 12) * 4;
Binary.CopyOverlapped (pixels, dst - offset, dst, count);
break;
case 5:
count = (count >> 8) & 0xFF;
input.BaseStream.Seek ((count - count / 4) * 4, SeekOrigin.Current);
count *= 4;
break;
case 5:
count = (count >> 8) & 0xFF;
input.BaseStream.Seek ((count - count / 4) * 4, SeekOrigin.Current);
count *= 4;
break;
default:
throw new InvalidFormatException();
}
dst += count;
default:
throw new InvalidFormatException();
}
if (0 != (meta.Flags & 0x10) && 0 != meta.BaseNameOffset)
dst += count;
}
if (0 != (meta.Flags & 0x10) && 0 != meta.BaseNameOffset)
{
try
{
try
var base_name = ReadBaseName (input, meta);
if (VFS.FileExists (base_name))
{
var base_name = ReadBaseName (input, meta);
if (VFS.FileExists (base_name))
using (var base_file = VFS.OpenSeekableStream (base_name))
{
using (var base_file = VFS.OpenSeekableStream (base_name))
{
var base_image = Read (base_name, base_file);
BlendImage (meta, pixels, base_image.Bitmap);
}
var base_image = Read (base_name, base_file);
BlendImage (meta, pixels, base_image.Bitmap);
}
}
catch (Exception X)
{
Trace.WriteLine (string.Format ("{0}: baseline image read error: {1}",
meta.FileName, X.Message), "[AGF]");
}
}
catch (Exception X)
{
Trace.WriteLine (string.Format ("{0}: baseline image read error: {1}",
meta.FileName, X.Message), "[AGF]");
}
}
return ImageData.Create (info, PixelFormats.Bgra32, null, pixels);
}
string ReadBaseName (BinaryReader input, AgfMetaData info)
string ReadBaseName (IBinaryStream input, AgfMetaData info)
{
input.BaseStream.Position = info.DataOffset + info.BaseNameOffset;
var name = new StringBuilder();
for (;;)
using (var reader = new BinaryReader (input.AsStream, Encoding.Unicode, true))
{
char c = input.ReadChar();
if (0 == c)
break;
name.Append (c);
var name = new StringBuilder();
for (;;)
{
char c = input.ReadChar();
if (0 == c)
break;
name.Append (c);
}
var dir_name = VFS.GetDirectoryName (info.FileName);
return VFS.CombinePath (dir_name, name.ToString());
}
var dir_name = VFS.GetDirectoryName (info.FileName);
return VFS.CombinePath (dir_name, name.ToString());
}
void BlendImage (AgfMetaData info, byte[] overlay, BitmapSource bitmap)

View File

@ -34,30 +34,30 @@ namespace GameRes.Formats.Creative
{
int m_version;
int m_header_size;
BinaryReader m_input;
IBinaryStream m_input;
WaveFormat m_format;
public WaveFormat Format { get { return m_format; } }
public VocReader (Stream input, byte[] header)
public VocReader (IBinaryStream input, byte[] header)
{
m_header_size = LittleEndian.ToUInt16 (header, 0x14);
if (m_header_size < 0x1A)
throw new InvalidFormatException();
m_version = LittleEndian.ToUInt16 (header, 0x16);
m_input = new ArcView.Reader (input);
m_input = input;
}
public Stream ConvertToPcm ()
{
m_input.BaseStream.Position = m_header_size;
m_input.Position = m_header_size;
bool format_read = false;
var pcm = new MemoryStream();
try
{
for (;;)
{
int block_type = m_input.BaseStream.ReadByte();
int block_type = m_input.ReadByte();
if (-1 == block_type || 0 == block_type)
break;
int block_size = m_input.ReadUInt16();
@ -96,7 +96,7 @@ namespace GameRes.Formats.Creative
Copy (block_size-12, pcm);
break;
default:
m_input.BaseStream.Seek (block_size, SeekOrigin.Current);
m_input.Seek (block_size, SeekOrigin.Current);
break;
}
if (codec != -1)
@ -144,14 +144,8 @@ namespace GameRes.Formats.Creative
}
#region IDisposable Members
bool _disposed = false;
public void Dispose ()
{
if (!_disposed)
{
m_input.Dispose();
_disposed = true;
}
}
#endregion
}
@ -164,18 +158,17 @@ namespace GameRes.Formats.Creative
public override uint Signature { get { return 0x61657243; } } // 'Crea'
public override bool CanWrite { get { return false; } }
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
var header = new byte[0x1A];
if (header.Length != file.Read (header, 0, header.Length))
var header = file.ReadHeader (0x1A);
if (!header.AsciiEqual ("Creative Voice File\x1A"))
return null;
if (!Binary.AsciiEqual (header, 0, "Creative Voice File\x1A"))
return null;
using (var reader = new VocReader (file, header))
using (var reader = new VocReader (file, header.ToArray()))
{
var pcm = reader.ConvertToPcm();
if (null == pcm)
return null;
file.Dispose();
return new RawPcmInput (pcm, reader.Format);
}
}

View File

@ -45,24 +45,22 @@ namespace GameRes.Formats.YellowPig
public override string Description { get { return "Yellow Pig image format"; } }
public override uint Signature { get { return 0; } }
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x11];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x11);
byte type = header[0];
if (type != 0 && type != 1)
return null;
var info = new GecMetaData
{
Type = type,
OffsetX = LittleEndian.ToInt16 (header, 1),
OffsetY = LittleEndian.ToInt16 (header, 3),
Width = LittleEndian.ToUInt16 (header, 5),
Height = LittleEndian.ToUInt16 (header, 7),
OffsetX = header.ToInt16 (1),
OffsetY = header.ToInt16 (3),
Width = header.ToUInt16 (5),
Height = header.ToUInt16 (7),
BPP = 0 == type ? 24 : 32,
AlphaOffset = LittleEndian.ToInt32 (header, 9),
DataOffset = LittleEndian.ToInt32 (header, 0xD),
AlphaOffset = header.ToInt32 (9),
DataOffset = header.ToInt32 (0xD),
};
if (info.OffsetX < 0 || info.OffsetY < 0 || info.Width <= 0 || info.Height <= 0
|| info.DataOffset < 0 || info.DataOffset > stream.Length)
@ -72,9 +70,9 @@ namespace GameRes.Formats.YellowPig
return info;
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var reader = new GecReader (stream, (GecMetaData)info);
var reader = new GecReader (stream.AsStream, (GecMetaData)info);
reader.Unpack();
return ImageData.CreateFlipped (info, reader.Format, null, reader.Data, reader.Stride);
}

View File

@ -36,9 +36,9 @@ namespace GameRes.Formats
public override string Description { get { return "UltraMarine3 audio format (Ogg/Vorbis)"; } }
public override uint Signature { get { return 0xAC9898B0; } } // ~'OggS'
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
return new OggInput (new Um3Stream (file));
return new OggInput (new Um3Stream (file.AsStream));
}
}

View File

@ -54,14 +54,12 @@ namespace GameRes.Formats.Bruns
Signatures = new uint[] { 0x434E4545, 0x5A4E4545 }; // 'EENC', 'EENZ'
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[8];
if (8 != stream.Read (header, 0, 8))
return null;
var header = stream.ReadHeader (8);
bool compressed = 'Z' == header[3];
uint key = LittleEndian.ToUInt32 (header, 4) ^ EencKey;
Stream input = new StreamRegion (stream, 8, true);
uint key = header.ToUInt32 (4) ^ EencKey;
Stream input = new StreamRegion (stream.AsStream, 8, true);
try
{
input = new EencStream (input, key);
@ -70,19 +68,22 @@ namespace GameRes.Formats.Bruns
input = new ZLibStream (input, CompressionMode.Decompress);
input = new SeekableStream (input);
}
var format = FindFormat (input);
if (null == format)
return null;
return new EencMetaData
using (var bin = new BinaryStream (input, stream.Name, true))
{
Width = format.Item2.Width,
Height = format.Item2.Height,
BPP = format.Item2.BPP,
Key = key,
Info = format.Item2,
Format = format.Item1,
Compressed = compressed,
};
var format = FindFormat (bin);
if (null == format)
return null;
return new EencMetaData
{
Width = format.Item2.Width,
Height = format.Item2.Height,
BPP = format.Item2.BPP,
Key = key,
Info = format.Item2,
Format = format.Item1,
Compressed = compressed,
};
}
}
finally
{
@ -90,17 +91,18 @@ namespace GameRes.Formats.Bruns
}
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (EencMetaData)info;
meta.Info.FileName = info.FileName;
Stream input = new StreamRegion (stream, 8, true);
Stream input = new StreamRegion (stream.AsStream, 8, true);
try
{
input = new EencStream (input, meta.Key);
if (meta.Compressed)
input = new ZLibStream (input, CompressionMode.Decompress);
return meta.Format.Read (input, meta.Info);
using (var bin = new BinaryStream (input, stream.Name, true))
return meta.Format.Read (input, meta.Info);
}
finally
{

View File

@ -43,41 +43,36 @@ namespace GameRes.Formats.CaramelBox
public override string Description { get { return "Caramel BOX image format"; } }
public override uint Signature { get { return 0x31626366; } } // 'fcb1'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x10];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x10);
return new FcbMetaData
{
Width = LittleEndian.ToUInt32 (header, 4),
Height = LittleEndian.ToUInt32 (header, 8),
Method = LittleEndian.ToInt32 (header, 12),
Width = header.ToUInt32 (4),
Height = header.ToUInt32 (8),
Method = header.ToInt32 (12),
BPP = 32,
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (FcbMetaData)info;
byte[] input;
if (1 == meta.Method)
{
stream.Position = 0x14;
using (var reader = new ArcView.Reader (stream))
{
int unpacked_size = Binary.BigEndian (reader.ReadInt32());
reader.ReadInt32(); // packed_size
input = new byte[unpacked_size];
using (var z = new ZLibStream (stream, CompressionMode.Decompress, true))
if (unpacked_size != z.Read (input, 0, unpacked_size))
throw new EndOfStreamException();
}
int unpacked_size = Binary.BigEndian (stream.ReadInt32());
stream.ReadInt32(); // packed_size
input = new byte[unpacked_size];
using (var z = new ZLibStream (stream.AsStream, CompressionMode.Decompress, true))
if (unpacked_size != z.Read (input, 0, unpacked_size))
throw new EndOfStreamException();
}
else if (0 == meta.Method)
{
stream.Position = 0x10;
using (var tz = new TzCompression (stream))
using (var tz = new TzCompression (stream.AsStream))
input = tz.Unpack();
}
else

View File

@ -39,12 +39,12 @@ namespace GameRes.Formats.Circus
OffsetMap = offset_map;
}
internal Stream OpenByOffset (uint offset)
internal IBinaryStream OpenByOffset (uint offset)
{
Entry entry;
if (!OffsetMap.TryGetValue (offset, out entry))
throw new FileNotFoundException();
return OpenEntry (entry);
return OpenBinaryEntry (entry);
}
}

View File

@ -48,31 +48,29 @@ namespace GameRes.Formats.Circus
public override string Description { get { return "Circus image format"; } }
public override uint Signature { get { return 0x47585243; } } // 'CRXG'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x14];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
int compression = LittleEndian.ToUInt16 (header, 0xC);
var header = stream.ReadHeader (0x14);
int compression = header.ToUInt16 (0xC);
if (compression < 1 || compression > 3)
return null;
int depth = LittleEndian.ToInt16 (header, 0x10);
int depth = header.ToInt16 (0x10);
var info = new CrxMetaData
{
Width = LittleEndian.ToUInt16 (header, 8),
Height = LittleEndian.ToUInt16 (header, 10),
OffsetX = LittleEndian.ToInt16 (header, 4),
OffsetY = LittleEndian.ToInt16 (header, 6),
Width = header.ToUInt16 (8),
Height = header.ToUInt16 (10),
OffsetX = header.ToInt16 (4),
OffsetY = header.ToInt16 (6),
BPP = 0 == depth ? 24 : 1 == depth ? 32 : 8,
Compression = compression,
CompressionFlags = LittleEndian.ToUInt16 (header, 0xE),
CompressionFlags = header.ToUInt16 (0xE),
Colors = depth,
Mode = LittleEndian.ToUInt16 (header, 0x12),
Mode = header.ToUInt16 (0x12),
};
return info;
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
using (var reader = new Reader (stream, (CrxMetaData)info))
{
@ -88,7 +86,7 @@ namespace GameRes.Formats.Circus
internal sealed class Reader : IDisposable
{
BinaryReader m_input;
IBinaryStream m_input;
byte[] m_output;
int m_width;
int m_height;
@ -103,7 +101,7 @@ namespace GameRes.Formats.Circus
public BitmapPalette Palette { get; private set; }
public int Stride { get { return m_stride; } }
public Reader (Stream input, CrxMetaData info)
public Reader (IBinaryStream input, CrxMetaData info)
{
m_width = (int)info.Width;
m_height = (int)info.Height;
@ -120,8 +118,8 @@ namespace GameRes.Formats.Circus
}
m_stride = (m_width * m_bpp / 8 + 3) & ~3;
m_output = new byte[m_height*m_stride];
m_input = new ArcView.Reader (input);
input.Position = 0x14;
m_input = input;
m_input.Position = 0x14;
if (8 == m_bpp)
ReadPalette (info.Colors);
}
@ -157,7 +155,7 @@ namespace GameRes.Formats.Circus
if (m_compression >= 3)
{
int count = m_input.ReadInt32();
m_input.BaseStream.Seek (count * 0x10, SeekOrigin.Current);
m_input.Seek (count * 0x10, SeekOrigin.Current);
}
if (0 != (m_flags & 0x10))
{
@ -321,7 +319,7 @@ namespace GameRes.Formats.Circus
{
int pixel_size = m_bpp / 8;
int src_stride = m_width * pixel_size;
using (var zlib = new ZLibStream (m_input.BaseStream, CompressionMode.Decompress, true))
using (var zlib = new ZLibStream (m_input.AsStream, CompressionMode.Decompress, true))
using (var src = new BinaryReader (zlib))
{
if (m_bpp >= 24)
@ -400,16 +398,8 @@ namespace GameRes.Formats.Circus
}
#region IDisposable Members
bool m_disposed = false;
public void Dispose ()
{
if (!m_disposed)
{
m_input.Dispose();
m_disposed = true;
}
GC.SuppressFinalize (this);
}
#endregion
}

View File

@ -50,17 +50,14 @@ namespace GameRes.Formats.Circus
Extensions = new string[] { "crx" };
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x24];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x24);
CrxdMetaData info = null;
if (Binary.AsciiEqual (header, 0x20, "CRXJ"))
if (header.AsciiEqual (0x20, "CRXJ"))
{
stream.Position = 0x28;
stream.Read (header, 0, 4);
uint diff_offset = LittleEndian.ToUInt32 (header, 0);
uint diff_offset = stream.ReadUInt32();
using (var crx = OpenByOffset (diff_offset))
{
if (null == crx)
@ -70,9 +67,10 @@ namespace GameRes.Formats.Circus
info.DiffOffset = diff_offset;
}
}
else if (Binary.AsciiEqual (header, 0x20, "CRXG"))
else if (header.AsciiEqual (0x20, "CRXG"))
{
using (var crx = new StreamRegion (stream, 0x20, true))
using (var crx_input = new StreamRegion (stream.AsStream, 0x20, true))
using (var crx = new BinaryStream (crx_input))
{
var diff_info = base.ReadMetaData (crx) as CrxMetaData;
if (null == diff_info)
@ -91,7 +89,7 @@ namespace GameRes.Formats.Circus
}
if (info != null)
{
info.BaseOffset = LittleEndian.ToUInt32 (header, 8);
info.BaseOffset = header.ToUInt32 (8);
info.BaseFileName = Binary.GetCString (header, 0xC, 0x14);
}
return info;
@ -108,27 +106,34 @@ namespace GameRes.Formats.Circus
return arc.OpenByOffset (offset);
}
Stream OpenDiffStream (Stream diff, CrxdMetaData info)
IBinaryStream OpenDiffStream (IBinaryStream diff, CrxdMetaData info)
{
Stream input;
if (0 == info.DiffOffset)
return new StreamRegion (diff, 0x20, true);
diff = OpenByOffset (info.DiffOffset);
if (null == diff)
throw new FileNotFoundException ("Referenced diff image not found");
return new StreamRegion (diff, 0x20);
{
input = new StreamRegion (diff.AsStream, 0x20, true);
}
else
{
diff = OpenByOffset (info.DiffOffset);
if (null == diff)
throw new FileNotFoundException ("Referenced diff image not found");
input = new StreamRegion (diff, 0x20);
}
return new BinaryStream (input);
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (CrxdMetaData)info;
Stream base_file = OpenByOffset (meta.BaseOffset);
IBinaryStream base_file = OpenByOffset (meta.BaseOffset);
if (null == base_file)
{
var dir_name = VFS.GetDirectoryName (meta.FileName);
var name = VFS.CombinePath (dir_name, meta.BaseFileName);
if (!VFS.FileExists (name))
throw new FileNotFoundException ("Base image not found", meta.BaseFileName);
base_file = VFS.OpenSeekableStream (name);
base_file = VFS.OpenBinaryStream (name);
}
using (base_file)
{

View File

@ -37,7 +37,7 @@ namespace GameRes.Formats.Pvns
public override string Description { get { return "PVNS engine compressed audio format"; } }
public override uint Signature { get { return 0x53564B4D; } } // 'MKVS'
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
using (var reader = new MvReader (file))
{
@ -52,7 +52,7 @@ namespace GameRes.Formats.Pvns
internal sealed class MvReader : IDisposable
{
BinaryReader m_input;
IBinaryStream m_input;
byte[] m_output;
WaveFormat m_format;
int m_channel_size;
@ -61,7 +61,7 @@ namespace GameRes.Formats.Pvns
public byte[] Data { get { return m_output; } }
public WaveFormat Format { get { return m_format; } }
public MvReader (Stream input)
public MvReader (IBinaryStream input)
{
var header = new byte[0x12];
input.Read (header, 0, header.Length);
@ -72,14 +72,14 @@ namespace GameRes.Formats.Pvns
m_format.SamplesPerSecond = LittleEndian.ToUInt16 (header, 0xA);
m_format.BlockAlign = (ushort)(m_format.Channels*m_format.BitsPerSample/8);
m_format.AverageBytesPerSecond = m_format.SamplesPerSecond*m_format.BlockAlign;
m_input = new ArcView.Reader (input);
m_input = input;
m_output = new byte[2 * m_format.Channels * m_channel_size];
m_samples = LittleEndian.ToInt32 (header, 0xE);
}
public void Unpack ()
{
m_input.BaseStream.Position = 0x12;
m_input.Position = 0x12;
var pre_sample1 = new int[0x400];
var pre_sample2 = new int[0x400];
var pre_sample3 = new int[0x140 * m_format.Channels];
@ -180,14 +180,8 @@ namespace GameRes.Formats.Pvns
}
#region IDisposable Members
bool _disposed = false;
public void Dispose ()
{
if (!_disposed)
{
m_input.Dispose();
_disposed = true;
}
}
#endregion

View File

@ -45,14 +45,11 @@ namespace GameRes.Formats.Pvns
public override string Description { get { return "PVNS engine image format"; } }
public override uint Signature { get { return 0x50425350; } } // 'PSBP'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x14];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x14);
stream.Seek (-0x13, SeekOrigin.End);
var tail = new byte[0x13];
stream.Read (tail, 0, tail.Length);
var tail = stream.ReadBytes (0x13);
for (int i = 4; i < 0x14; ++i)
{
header[i] ^= tail[tail.Length - 3 + (i & 1)];
@ -60,18 +57,18 @@ namespace GameRes.Formats.Pvns
}
return new PsbMetaData
{
Width = LittleEndian.ToUInt16 (header, 0x0E),
Height = LittleEndian.ToUInt16 (header, 0x10),
BPP = LittleEndian.ToUInt16 (header, 0x12),
Method = LittleEndian.ToUInt16 (header, 0x0C),
TableOffset = LittleEndian.ToInt32 (header, 4),
DataOffset = LittleEndian.ToInt32 (header, 8),
Width = header.ToUInt16 (0x0E),
Height = header.ToUInt16 (0x10),
BPP = header.ToUInt16 (0x12),
Method = header.ToUInt16 (0x0C),
TableOffset = header.ToInt32 (4),
DataOffset = header.ToInt32 (8),
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var reader = new PsbReader (stream, (PsbMetaData)info);
var reader = new PsbReader (stream.AsStream, (PsbMetaData)info);
reader.Unpack();
return ImageData.Create (info, reader.Format, null, reader.Data);
}

View File

@ -38,21 +38,21 @@ namespace GameRes.Formats.Cri
public override string Description { get { return "CRI MiddleWare ADPCM audio"; } }
public override uint Signature { get { return 0; } }
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
uint signature = FormatCatalog.ReadSignature (file);
uint signature = file.Signature;
if (0x80 != (signature & 0xFFFF))
return null;
uint header_size = Binary.BigEndian (signature & 0xFFFF0000);
if (header_size < 0x10 || header_size >= file.Length)
return null;
var header = new byte[header_size];
if (header.Length != file.Read (header, 0, header.Length))
var header = file.ReadBytes (header_size);
if (header.Length != header_size)
return null;
if (!Binary.AsciiEqual (header, header.Length-6, "(c)CRI"))
return null;
return new AdxInput (file, header);
return new AdxInput (file.AsStream, header);
}
}

View File

@ -49,9 +49,9 @@ namespace GameRes.Formats.Cri
static readonly Tuple<uint, uint> DefaultKey = Tuple.Create (0x30DBE1ABu, 0xCC554639u);
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
return new HcaInput (file, ConversionFormat.IeeeFloat, DefaultKey);
return new HcaInput (file.AsStream, ConversionFormat.IeeeFloat, DefaultKey);
}
}

View File

@ -42,22 +42,24 @@ namespace GameRes.Formats.Cri
Signatures = new uint[] { 0 };
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
uint unpacked_size = FormatCatalog.ReadSignature (stream);
uint unpacked_size = stream.Signature;
if (unpacked_size <= 0x20 || unpacked_size > 0x5000000) // ~83MB
return null;
using (var lzss = new LzssStream (stream, LzssMode.Decompress, true))
using (var lzss = new LzssStream (stream.AsStream, LzssMode.Decompress, true))
using (var input = new SeekableStream (lzss))
return base.ReadMetaData (input);
using (var xtx = new BinaryStream (input))
return base.ReadMetaData (xtx);
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
stream.Position = 4;
using (var lzss = new LzssStream (stream, LzssMode.Decompress, true))
using (var lzss = new LzssStream (stream.AsStream, LzssMode.Decompress, true))
using (var input = new SeekableStream (lzss))
return base.Read (input, info);
using (var xtx = new BinaryStream (input))
return base.Read (xtx, info);
}
public override void Write (Stream file, ImageData image)

View File

@ -51,11 +51,9 @@ namespace GameRes.Formats.Cri
Signatures = new uint[] { 0x00787478, 0 };
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x20];
if (0x20 != stream.Read (header, 0, 0x20))
return null;
var header = stream.ReadHeader (0x20).ToArray();
if (!Binary.AsciiEqual (header, 0, "xtx\0"))
{
var header_size = LittleEndian.ToUInt32 (header, 0);
@ -87,9 +85,9 @@ namespace GameRes.Formats.Cri
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var reader = new XtxReader (stream, (XtxMetaData)info);
var reader = new XtxReader (stream.AsStream, (XtxMetaData)info);
var pixels = reader.Unpack();
return ImageData.Create (info, reader.Format, null, pixels);
}

View File

@ -41,14 +41,15 @@ namespace GameRes.Formats.Crowd
public override string Description { get { return "ANIM encrypted image"; } }
public override uint Signature { get { return 0x01000000; } }
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var key = new byte[0x10];
stream.Position = 4;
if (key.Length != stream.Read (key, 0, key.Length))
return null;
using (var enc = new InputProxyStream (stream, true))
using (var input = new CryptoStream (enc, new GaxTransform (key), CryptoStreamMode.Read))
using (var enc = new InputProxyStream (stream.AsStream, true))
using (var crypto = new CryptoStream (enc, new GaxTransform (key), CryptoStreamMode.Read))
using (var input = new BinaryStream (crypto, stream.Name))
{
var info = Png.ReadMetaData (input);
if (null == info)
@ -65,11 +66,12 @@ namespace GameRes.Formats.Crowd
}
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (GaxMetaData)info;
using (var enc = new StreamRegion (stream, 0x14, true))
using (var input = new CryptoStream (enc, new GaxTransform (meta.Key), CryptoStreamMode.Read))
using (var enc = new StreamRegion (stream.AsStream, 0x14, true))
using (var crypto = new CryptoStream (enc, new GaxTransform (meta.Key), CryptoStreamMode.Read))
using (var input = new BinaryStream (crypto, stream.Name))
return Png.Read (input, info);
}

View File

@ -59,7 +59,7 @@ namespace GameRes.Formats.Cyberworks
set { KnownKeys = ((TinkAudioScheme)value).KnownKeys; }
}
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
var header = new byte[Math.Min (0xE1F, file.Length)];
if (0x10 != file.Read (header, 0, 0x10))
@ -89,8 +89,9 @@ namespace GameRes.Formats.Cyberworks
if (header.Length >= file.Length)
input = new MemoryStream (header);
else
input = new PrefixStream (header, new StreamRegion (file, file.Position));
var sound = OggAudio.Instance.TryOpen (input);
input = new PrefixStream (header, new StreamRegion (file.AsStream, file.Position));
var ogg = new BinaryStream (input, file.Name);
var sound = OggAudio.Instance.TryOpen (ogg);
if (sound != null && header.Length >= file.Length)
file.Dispose();
return sound;

View File

@ -54,37 +54,34 @@ namespace GameRes.Formats.EmonEngine
Extensions = new string[] { "bmp" };
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
using (var reader = new ArcView.Reader (stream))
{
reader.ReadInt32();
var info = new EmMetaData();
info.LzssFrameSize = reader.ReadUInt16();
info.LzssInitPos = reader.ReadUInt16();
info.BPP = reader.ReadUInt16() & 0xFF;
info.Width = reader.ReadUInt16();
info.Height = reader.ReadUInt16();
info.Colors = reader.ReadUInt16();
info.Stride = reader.ReadInt32();
info.OffsetX = reader.ReadInt32();
info.OffsetY = reader.ReadInt32();
info.DataOffset = 40;
return info;
}
stream.ReadInt32();
var info = new EmMetaData();
info.LzssFrameSize = stream.ReadUInt16();
info.LzssInitPos = stream.ReadUInt16();
info.BPP = stream.ReadUInt16() & 0xFF;
info.Width = stream.ReadUInt16();
info.Height = stream.ReadUInt16();
info.Colors = stream.ReadUInt16();
info.Stride = stream.ReadInt32();
info.OffsetX = stream.ReadInt32();
info.OffsetY = stream.ReadInt32();
info.DataOffset = 40;
return info;
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (EmMetaData)info;
stream.Position = meta.DataOffset;
BitmapPalette palette = null;
if (meta.Colors != 0)
palette = ReadPalette (stream, Math.Max (meta.Colors, 3));
palette = ReadPalette (stream.AsStream, Math.Max (meta.Colors, 3));
var pixels = new byte[meta.Stride * (int)info.Height];
if (meta.LzssFrameSize != 0)
{
using (var lzss = new LzssStream (stream, LzssMode.Decompress, true))
using (var lzss = new LzssStream (stream.AsStream, LzssMode.Decompress, true))
{
lzss.Config.FrameSize = meta.LzssFrameSize;
lzss.Config.FrameInitPos = meta.LzssInitPos;

View File

@ -36,7 +36,7 @@ namespace GameRes.Formats
public override uint Signature { get { return 0; } }
public override bool CanWrite { get { return true; } }
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
int c1 = stream.ReadByte();
int c2 = stream.ReadByte();
@ -46,17 +46,18 @@ namespace GameRes.Formats
return base.ReadMetaData (bmp);
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
using (var bmp = OpenAsBitmap (stream))
return base.Read (bmp, info);
}
Stream OpenAsBitmap (Stream input)
IBinaryStream OpenAsBitmap (IBinaryStream input)
{
var header = new byte[2] { (byte)'B', (byte)'M' };
input = new StreamRegion (input, 2, true);
return new PrefixStream (header, input);
Stream stream = new StreamRegion (input.AsStream, 2, true);
stream = new PrefixStream (header, input);
return new BinaryStream (stream, input.Name);
}
public override void Write (Stream file, ImageData image)

View File

@ -37,7 +37,7 @@ namespace GameRes.Formats.BaseUnit
public override string Description { get { return "IPAC ADPCM audio format"; } }
public override uint Signature { get { return 0x32545357; } } // 'WST2'
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
var adpcm_data = new byte[0x20];
file.Position = 12;

View File

@ -38,20 +38,18 @@ namespace GameRes.Formats.BaseUnit
public override string Description { get { return "IPAC image format"; } }
public override uint Signature { get { return 0x32534549; } } // 'IES2'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x14];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x14);
return new ImageMetaData
{
Width = LittleEndian.ToUInt32 (header, 0x08),
Height = LittleEndian.ToUInt32 (header, 0x0C),
BPP = LittleEndian.ToInt32 (header, 0x10),
Width = header.ToUInt32 (0x08),
Height = header.ToUInt32 (0x0C),
BPP = header.ToInt32 (0x10),
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
if (24 == info.BPP)
{
@ -78,7 +76,7 @@ namespace GameRes.Formats.BaseUnit
else if (8 == info.BPP)
{
stream.Position = 0x20;
var palette = ReadPalette (stream);
var palette = ReadPalette (stream.AsStream);
var pixels = new byte[info.Width * info.Height];
if (pixels.Length != stream.Read (pixels, 0, pixels.Length))
throw new EndOfStreamException();

View File

@ -43,7 +43,7 @@ namespace GameRes.Formats.Ivory
Signatures = new uint[] { 0x20585066, 0x4B525463 };
}
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
var header = new byte[0x24];
if (8 != file.Read (header, 0, 8))
@ -77,12 +77,12 @@ namespace GameRes.Formats.Ivory
};
format.BlockAlign = (ushort)(format.BitsPerSample * format.Channels / 8);
format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;
var input = new StreamRegion (file, start_offset, data_length);
var input = new StreamRegion (file.AsStream, start_offset, data_length);
return new RawPcmInput (input, format);
}
else if (2 == type)
{
using (var decoder = new TrkDecoder (file, header, start_offset, data_length))
using (var decoder = new TrkDecoder (file.AsStream, header, start_offset, data_length))
{
var pcm = decoder.Decode();
return new RawPcmInput (new MemoryStream (pcm), decoder.Format);

View File

@ -47,78 +47,73 @@ namespace GameRes.Formats.Ivory
public override string Description { get { return "Ivory image format"; } }
public override uint Signature { get { return 0x1A444D4D; } } // 'MMD'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x18];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x18);
var info = new MmdMetaData
{
Width = LittleEndian.ToUInt16 (header, 4),
Height = LittleEndian.ToUInt16 (header, 6),
Width = header.ToUInt16 (4),
Height = header.ToUInt16 (6),
BPP = 8,
Size1 = LittleEndian.ToInt32 (header, 8),
Size2 = LittleEndian.ToInt32 (header, 0x0C),
Size3 = LittleEndian.ToInt32 (header, 0x10),
Colors = LittleEndian.ToInt32 (header, 0x14),
Size1 = header.ToInt32 (8),
Size2 = header.ToInt32 (0x0C),
Size3 = header.ToInt32 (0x10),
Colors = header.ToInt32 (0x14),
};
if (info.Size1 <= 0 || info.Size2 <= info.Size1 || info.Size3 <= 0)
return null;
return info;
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream input, ImageMetaData info)
{
var meta = (MmdMetaData)info;
var pixels = new byte[info.Width * info.Height];
stream.Position = 0x18;
using (var input = new ArcView.Reader (stream))
input.Position = 0x18;
var buf1 = input.ReadBytes (meta.Size1);
var buf2 = input.ReadBytes (meta.Size2 - meta.Size1);
int w = (int)info.Width / 4;
var line = new byte[w];
int mask = 0x80;
int b1 = 0;
int b2 = 0;
int dst = 0;
for (int y = (int)info.Height; y > 0; --y)
{
var buf1 = input.ReadBytes (meta.Size1);
var buf2 = input.ReadBytes (meta.Size2 - meta.Size1);
int w = (int)info.Width / 4;
var line = new byte[w];
int mask = 0x80;
int b1 = 0;
int b2 = 0;
int dst = 0;
for (int y = (int)info.Height; y > 0; --y)
for (int x = 0; x < w; ++x)
{
for (int x = 0; x < w; ++x)
if (0 != (mask & buf1[b1]))
{
if (0 != (mask & buf1[b1]))
line[x] ^= buf2[b2++];
}
mask >>= 1;
if (0 == mask)
{
mask = 0x80;
++b1;
}
byte p = line[x];
int q = p >> 4;
for (int j = 0; j < 2; ++j)
{
if (0 != q)
{
line[x] ^= buf2[b2++];
int offset = ShiftTable[q + 16] + (int)info.Width * ShiftTable[q];
int src = dst - offset;
pixels[dst++] = pixels[src];
pixels[dst++] = pixels[src+1];
}
mask >>= 1;
if (0 == mask)
else
{
mask = 0x80;
++b1;
}
byte p = line[x];
int q = p >> 4;
for (int j = 0; j < 2; ++j)
{
if (0 != q)
{
int offset = ShiftTable[q + 16] + (int)info.Width * ShiftTable[q];
int src = dst - offset;
pixels[dst++] = pixels[src];
pixels[dst++] = pixels[src+1];
}
else
{
input.Read (pixels, dst, 2);
dst += 2;
}
q = p & 0xF;
input.Read (pixels, dst, 2);
dst += 2;
}
q = p & 0xF;
}
}
}
stream.Position = 0x18 + meta.Size2 + meta.Size3;
var palette = ReadPalette (stream, meta.Colors);
input.Position = 0x18 + meta.Size2 + meta.Size3;
var palette = ReadPalette (input.AsStream, meta.Colors);
return ImageData.Create (info, PixelFormats.Indexed8, palette, pixels);
}

View File

@ -37,19 +37,19 @@ namespace GameRes.Formats.Ivory
public override string Description { get { return "Ivory image format"; } }
public override uint Signature { get { return 0; } }
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var wh = FormatCatalog.ReadSignature (stream);
var wh = stream.Signature;
uint width = wh & 0xFFFF;
uint height = wh >> 16;
if (0 == width || width > 800 || 0 == height || height > 600)
return null;
if (!IsValidInput (stream, width, height))
if (!IsValidInput (stream.AsStream, width, height))
return null;
return new ImageMetaData { Width = width, Height = height, BPP = 24 };
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
stream.Position = 4;
var pixels = new byte[3 * info.Width * info.Height];

View File

@ -53,11 +53,11 @@ namespace GameRes.Formats.Ivory
public override string Description { get { return "Ivory image format"; } }
public override uint Signature { get { return 0x20475366; } } // 'fSG '
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
stream.Position = 8;
var header = new byte[0x24];
if (header.Length != stream.Read (header, 0, header.Length))
var header = stream.ReadBytes (0x24);
if (header.Length != 0x24)
return null;
int header_size = LittleEndian.ToInt32 (header, 8);
if (Binary.AsciiEqual (header, "cRGB"))
@ -90,7 +90,7 @@ namespace GameRes.Formats.Ivory
return null;
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (SgMetaData)info;
if (SgType.cRGB == meta.Type)
@ -107,11 +107,11 @@ namespace GameRes.Formats.Ivory
}
}
ImageData ReadJpeg (Stream stream, SgMetaData info)
ImageData ReadJpeg (IBinaryStream stream, SgMetaData info)
{
stream.Position = info.DataOffset;
var input = new byte[info.DataSize];
if (input.Length != stream.Read (input, 0, input.Length))
var input = stream.ReadBytes (info.DataSize);
if (input.Length != info.DataSize)
throw new EndOfStreamException();
PakOpener.Decrypt (input, info.JpegKey);
using (var img = new MemoryStream (input))
@ -131,7 +131,7 @@ namespace GameRes.Formats.Ivory
internal sealed class SgRgbReader : IDisposable
{
BinaryReader m_input;
IBinaryStream m_input;
SgMetaData m_info;
int m_width;
int m_height;
@ -148,7 +148,7 @@ namespace GameRes.Formats.Ivory
{
if (info.Type != SgType.cRGB || !(0x18 == info.BPP || 0x20 == info.BPP))
throw new InvalidFormatException();
m_input = new ArcView.Reader (input);
m_input = input;
m_info = info;
m_width = (int)info.Width;
m_height = (int)info.Height;
@ -158,7 +158,7 @@ namespace GameRes.Formats.Ivory
public void Unpack ()
{
m_input.BaseStream.Position = m_info.DataOffset;
m_input.Position = m_info.DataOffset;
switch (m_info.RgbMode)
{
case 0: UnpackV0(); break;
@ -243,11 +243,11 @@ namespace GameRes.Formats.Ivory
var index = new int[m_height];
for (int i = 0; i < m_height; ++i)
index[i] = m_input.ReadInt32();
var data_pos = m_input.BaseStream.Position;
var data_pos = m_input.Position;
int dst = 0;
for (int y = 0; y < m_height; ++y)
{
m_input.BaseStream.Position = data_pos + index[y];
m_input.Position = data_pos + index[y];
for (int x = 0; x < m_width; )
{
int ctl = m_input.ReadByte();
@ -282,9 +282,9 @@ namespace GameRes.Formats.Ivory
var index = new int[m_height];
for (int i = 0; i < m_height; ++i)
index[i] = m_input.ReadInt32();
var data_pos = m_input.BaseStream.Position;
var data_pos = m_input.Position;
int dst = 0;
using (var bits = new LsbBitStream (m_input.BaseStream, true))
using (var bits = new LsbBitStream (m_input.AsStream, true))
{
for (int y = 0; y < m_height; ++y)
{
@ -358,14 +358,8 @@ namespace GameRes.Formats.Ivory
}
#region IDisposable Members
bool _disposed = false;
public void Dispose ()
{
if (!_disposed)
{
m_input.Dispose();
_disposed = true;
}
}
#endregion
}

View File

@ -45,22 +45,21 @@ namespace GameRes.Formats.KScript
public override string Description { get { return "KScript image format"; } }
public override uint Signature { get { return 0x48505247; } } // 'GRPH'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x1C];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x1C);
byte key = (byte)(header[4] ^ header[5]);
int data_offset = 0x14;
int x = 0, y = 0;
if (0 != header[0xC])
{
data_offset += LittleEndian.ToInt32 (header, 0x10) / 0x10 * 0x18;
x = LittleEndian.ToInt32 (header, 0x14);
y = LittleEndian.ToInt32 (header, 0x18);
data_offset += header.ToInt32 (0x10) / 0x10 * 0x18;
x = header.ToInt32 (0x14);
y = header.ToInt32 (0x18);
}
using (var input = new StreamRegion (stream, data_offset, true))
using (var png = new CryptoStream (input, new XorTransform (key), CryptoStreamMode.Read))
using (var input = new StreamRegion (stream.AsStream, data_offset, true))
using (var crypto = new CryptoStream (input, new XorTransform (key), CryptoStreamMode.Read))
using (var png = new BinaryStream (crypto, stream.Name))
{
var info = Png.ReadMetaData (png);
if (null == info)
@ -74,16 +73,17 @@ namespace GameRes.Formats.KScript
BPP = info.BPP,
Key = key,
DataOffset = data_offset,
DataLength = LittleEndian.ToInt32 (header, 8),
DataLength = header.ToInt32 (8),
};
}
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (KgpMetaData)info;
using (var input = new StreamRegion (stream, meta.DataOffset, true))
using (var png = new CryptoStream (input, new XorTransform (meta.Key), CryptoStreamMode.Read))
using (var input = new StreamRegion (stream.AsStream, meta.DataOffset, true))
using (var crypto = new CryptoStream (input, new XorTransform (meta.Key), CryptoStreamMode.Read))
using (var png = new BinaryStream (crypto, stream.Name))
return Png.Read (png, info);
}

View File

@ -43,27 +43,24 @@ namespace GameRes.Formats.KScript
public override string Description { get { return "KScript grayscale image format"; } }
public override uint Signature { get { return 0x4D4C534B; } } // 'KSLM'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x14];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
var header = stream.ReadHeader (0x14);
return new KslMetaData
{
Width = LittleEndian.ToUInt32 (header, 0xC),
Height = LittleEndian.ToUInt32 (header, 0x10),
Width = header.ToUInt32 (0xC),
Height = header.ToUInt32 (0x10),
BPP = 8,
Key = (byte)(header[4] ^ header[5]),
DataLength = LittleEndian.ToInt32 (header, 8),
DataLength = header.ToInt32 (8),
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
var meta = (KslMetaData)info;
var pixels = new byte[meta.DataLength];
stream.Position = 0x14;
stream.Read (pixels, 0, pixels.Length);
var pixels = stream.ReadBytes (meta.DataLength);
for (int i = 0; i < pixels.Length; ++i)
pixels[i] ^= meta.Key;
return ImageData.Create (info, PixelFormats.Gray8, null, pixels);

View File

@ -43,17 +43,15 @@ namespace GameRes.Formats.Leaf
Extensions = new string[] { "g" };
}
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
var header = new byte[0x1C];
if (header.Length != file.Read (header, 0, header.Length))
var header = file.ReadHeader (0x1C);
if (header.AsciiEqual ("OggS") || header.AsciiEqual ("RIFF"))
return null;
if (Binary.AsciiEqual (header, "OggS") || Binary.AsciiEqual (header, "RIFF"))
return null;
if (header[4] != 0 || header[5] != 2 || LittleEndian.ToInt64 (header, 6) != 0)
if (header[4] != 0 || header[5] != 2 || header.ToInt64 (6) != 0)
return null;
file.Position = 0;
var input = new GStream (file);
var input = new GStream (file.AsStream);
return new OggInput (new SeekableStream (input));
}
}

View File

@ -41,27 +41,25 @@ namespace GameRes.Formats.Leaf
Extensions = new string[] { "w" };
}
public override SoundInput TryOpen (Stream file)
public override SoundInput TryOpen (IBinaryStream file)
{
var header = new byte[0x12];
if (header.Length != file.Read (header, 0, header.Length))
return null;
var header = file.ReadHeader (0x12);
var format = new WaveFormat
{
FormatTag = 1,
Channels = header[0],
SamplesPerSecond = LittleEndian.ToUInt16 (header, 2),
AverageBytesPerSecond = LittleEndian.ToUInt32 (header, 6),
SamplesPerSecond = header.ToUInt16 (2),
AverageBytesPerSecond = header.ToUInt32 (6),
BlockAlign = header[1],
BitsPerSample = LittleEndian.ToUInt16 (header, 4),
BitsPerSample = header.ToUInt16 (4),
};
uint pcm_size = LittleEndian.ToUInt32 (header, 0xA);
uint pcm_size = header.ToUInt32 (0xA);
if (0 == pcm_size || 0 == format.AverageBytesPerSecond || format.BitsPerSample < 8
|| 0 == format.Channels || format.Channels > 8
|| (format.BlockAlign * format.SamplesPerSecond != format.AverageBytesPerSecond)
|| (pcm_size + 0x12 != file.Length))
return null;
var pcm = new StreamRegion (file, 0x12, pcm_size);
var pcm = new StreamRegion (file.AsStream, 0x12, pcm_size);
return new RawPcmInput (pcm, format);
}
}

View File

@ -44,28 +44,26 @@ namespace GameRes.Formats.Leaf
Signatures = new uint[] { 0x1866676C, 0x2066676C, 0x0966676C };
}
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[8];
if (8 != stream.Read (header, 0, 8))
return null;
var header = stream.ReadHeader (8);
int bpp = header[3];
return new ImageMetaData
{
Width = LittleEndian.ToUInt16 (header, 4),
Height = LittleEndian.ToUInt16 (header, 6),
Width = header.ToUInt16 (4),
Height = header.ToUInt16 (6),
BPP = 9 == bpp ? 8 : bpp,
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
int stride = (int)info.Width * info.BPP / 8;
var pixels = new byte[stride * (int)info.Height];
stream.Position = 12;
BitmapPalette palette = null;
if (8 == info.BPP)
palette = ReadPalette (stream);
palette = ReadPalette (stream.AsStream);
if (pixels.Length != stream.Read (pixels, 0, pixels.Length))
throw new EndOfStreamException();
PixelFormat format = 24 == info.BPP ? PixelFormats.Bgr24

View File

@ -49,23 +49,21 @@ namespace GameRes.Formats.Leaf
public override string Description { get { return "Leaf image format"; } }
public override uint Signature { get { return 0; } }
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = new byte[0x20];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
int type = LittleEndian.ToUInt16 (header, 0x10);
var header = stream.ReadHeader (0x20);
int type = header.ToUInt16 (0x10);
if (0x0C == type)
{
int count = LittleEndian.ToInt32 (header, 0);
int count = header.ToInt32 (0);
if (!ArchiveFormat.IsSaneCount (count))
return null;
int block_size = LittleEndian.ToInt32 (header, 4);
int block_size = header.ToInt32 (4);
if (block_size <= 0)
return null;
int bpp = LittleEndian.ToUInt16 (header, 0x12);
uint width = LittleEndian.ToUInt16 (header, 0x14);
uint height = LittleEndian.ToUInt16 (header, 0x16);
int bpp = header.ToUInt16 (0x12);
uint width = header.ToUInt16 (0x14);
uint height = header.ToUInt16 (0x16);
if (bpp != 32 || 0 == width || 0 == height)
return null;
return new PxMetaData
@ -76,34 +74,35 @@ namespace GameRes.Formats.Leaf
Type = type,
FrameCount = count,
BlockSize = block_size,
BlocksWidth = LittleEndian.ToUInt16 (header, 0x1C),
BlocksHeight = LittleEndian.ToUInt16 (header, 0x1E),
BlocksWidth = header.ToUInt16 (0x1C),
BlocksHeight = header.ToUInt16 (0x1E),
};
}
else if (0x80 == type || 0x90 == type)
{
if (!Binary.AsciiEqual (header, 0x14, "Leaf"))
if (!header.AsciiEqual (0x14, "Leaf"))
return null;
int count = LittleEndian.ToInt32 (header, 4);
int count = header.ToInt32 (4);
if (!ArchiveFormat.IsSaneCount (count))
return null;
if (0x20 != stream.Read (header, 0, 0x20))
var header_ex = stream.ReadBytes (0x20);
if (0x20 != header_ex.Length)
return null;
if (0x0A != LittleEndian.ToUInt16 (header, 0x10))
if (0x0A != LittleEndian.ToUInt16 (header_ex, 0x10))
return null;
return new PxMetaData
{
Width = LittleEndian.ToUInt32 (header, 0),
Height = LittleEndian.ToUInt32 (header, 0),
BPP = LittleEndian.ToUInt16 (header, 0x12),
Type = type,
Width = LittleEndian.ToUInt32 (header_ex, 0),
Height = LittleEndian.ToUInt32 (header_ex, 0),
BPP = LittleEndian.ToUInt16 (header_ex, 0x12),
Type = type,
FrameCount = count,
};
}
return null;
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
using (var reader = new PxReader (stream, (PxMetaData)info))
{
@ -120,7 +119,7 @@ namespace GameRes.Formats.Leaf
internal sealed class PxReader : IDisposable
{
BinaryReader m_input;
IBinaryStream m_input;
PxMetaData m_info;
byte[] m_output;
int m_pixel_size;
@ -131,9 +130,9 @@ namespace GameRes.Formats.Leaf
public int Stride { get { return m_stride; } }
public int FrameCount { get { return m_info.FrameCount; } }
public PxReader (Stream input, PxMetaData info)
public PxReader (IBinaryStream input, PxMetaData info)
{
m_input = new ArcView.Reader (input);
m_input = input;
m_info = info;
m_pixel_size = m_info.BPP / 8;
m_stride = (int)m_info.Width * m_pixel_size;
@ -156,10 +155,9 @@ namespace GameRes.Formats.Leaf
void Unpack0C (int frame)
{
var stream = m_input.BaseStream;
int block_count = m_info.BlocksWidth * m_info.BlocksHeight;
var block_table = new ushort[block_count];
stream.Position = 0x20 + frame * block_count * 2;
m_input.Position = 0x20 + frame * block_count * 2;
for (int i = 0; i < block_count; ++i)
block_table[i] = m_input.ReadUInt16();
int data_pos = 0x20 + FrameCount * block_count * 2;
@ -174,7 +172,7 @@ namespace GameRes.Formats.Leaf
int block_num = block_table[current_block++];
if (block_num != 0)
{
stream.Position = data_pos + (block_num - 1) * block_length;
m_input.Position = data_pos + (block_num - 1) * block_length;
int block_width = m_input.ReadByte() - 2;
int block_height = m_input.ReadByte() - 2;
int line_length = block_width * m_pixel_size;
@ -182,7 +180,7 @@ namespace GameRes.Formats.Leaf
{
m_input.Read (m_output, dst, line_length);
dst += m_stride;
stream.Seek (8, SeekOrigin.Current);
m_input.Seek (8, SeekOrigin.Current);
}
}
}
@ -192,7 +190,7 @@ namespace GameRes.Formats.Leaf
void Unpack90 (int frame)
{
m_input.BaseStream.Position = 0x40 + frame * (0x20 + m_output.Length);
m_input.Position = 0x40 + frame * (0x20 + m_output.Length);
if (m_output.Length != m_input.Read (m_output, 0, m_output.Length))
throw new EndOfStreamException();
}
@ -203,14 +201,8 @@ namespace GameRes.Formats.Leaf
}
#region IDisposable Members
bool _disposed = false;
public void Dispose ()
{
if (!_disposed)
{
m_input.Dispose();
_disposed = true;
}
}
#endregion
}

View File

@ -46,41 +46,38 @@ namespace GameRes.Formats.Elf
public override string Description { get { return "Elf GPH image format"; } }
public override uint Signature { get { return 0x1D485047; } } // 'GPH\x1D'
public override ImageMetaData ReadMetaData (Stream stream)
public override ImageMetaData ReadMetaData (IBinaryStream input)
{
stream.Position = 4;
using (var input = new ArcView.Reader (stream))
input.Position = 4;
int frame_count = input.ReadUInt16();
int frame_offset = input.ReadInt32();
if (0 == frame_count || frame_offset > input.Length)
return null;
input.Position = frame_offset;
int frame_length = input.ReadInt32();
int flags = input.ReadUInt16();
if (0 == (flags & 4))
input.Seek (0x20, SeekOrigin.Current);
int left = input.ReadInt16();
int top = input.ReadInt16();
int right = input.ReadInt16() + 1;
int bottom = input.ReadInt16() + 1;
left *= 2;
right *= 2;
return new GphMetaData
{
int frame_count = input.ReadUInt16();
int frame_offset = input.ReadInt32();
if (0 == frame_count || frame_offset > stream.Length)
return null;
stream.Position = frame_offset;
int frame_length = input.ReadInt32();
int flags = input.ReadUInt16();
if (0 == (flags & 4))
stream.Seek (0x20, SeekOrigin.Current);
int left = input.ReadInt16();
int top = input.ReadInt16();
int right = input.ReadInt16() + 1;
int bottom = input.ReadInt16() + 1;
left *= 2;
right *= 2;
return new GphMetaData
{
Width = (uint)(right - left),
Height = (uint)(bottom - top),
OffsetX = left,
OffsetY = top,
BPP = 4,
DataOffset = frame_offset+4,
DataSize = frame_length,
Flags = flags,
};
}
Width = (uint)(right - left),
Height = (uint)(bottom - top),
OffsetX = left,
OffsetY = top,
BPP = 4,
DataOffset = frame_offset+4,
DataSize = frame_length,
Flags = flags,
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{
using (var reader = new GphReader (stream, (GphMetaData)info))
{
@ -97,7 +94,7 @@ namespace GameRes.Formats.Elf
internal sealed class GphReader : IDisposable
{
BinaryReader m_input;
IBinaryStream m_input;
GphMetaData m_info;
byte[] m_output;
@ -106,9 +103,9 @@ namespace GameRes.Formats.Elf
public BitmapPalette Palette { get; private set; }
public int Stride { get; private set; }
public GphReader (Stream input, GphMetaData info)
public GphReader (IBinaryStream input, GphMetaData info)
{
m_input = new ArcView.Reader (input);
m_input = input;
m_info = info;
Stride = (int)m_info.Width / 2;
m_output = new byte[Stride * (int)m_info.Height];
@ -437,14 +434,8 @@ namespace GameRes.Formats.Elf
}
#region IDisposable Members
bool _disposed = false;
public void Dispose ()
{
if (!_disposed)
{
m_input.Dispose();
_disposed = true;
}
}
#endregion
}

View File

@ -133,9 +133,7 @@ namespace GameRes
{
if (!m_own_copy)
{
m_source = ToArray();
m_offset = 0;
m_own_copy = true;
Reclaim();
}
m_source[pos] = value;
}
@ -160,6 +158,13 @@ namespace GameRes
Array.Copy (m_source, m_offset, copy, 0, m_count);
return copy;
}
internal void Reclaim ()
{
m_source = ToArray();
m_offset = 0;
m_own_copy = true;
}
}
public static class CowByteArray
@ -198,6 +203,24 @@ namespace GameRes
{
return (long)ToUInt64 (arr, index);
}
public static bool AsciiEqual (this CowArray<byte> arr, int index, string str)
{
arr.Reclaim();
return Binary.AsciiEqual (arr.ToArray(), index, str);
}
public static bool AsciiEqual (this CowArray<byte> arr, string str)
{
arr.Reclaim();
return Binary.AsciiEqual (arr.ToArray(), str);
}
public static string GetCString (this CowArray<byte> arr, int index, int length_limit)
{
arr.Reclaim();
return Binary.GetCString (arr.ToArray(), index, length_limit);
}
}
public class BinaryStream : Stream, IBinaryStream
@ -224,22 +247,22 @@ namespace GameRes
m_buffer = new byte[0x10];
m_buffer_pos = 0;
m_buffer_end = 0;
m_signature = new Lazy<uint> (ReadSignature);
m_header_size = 0;
Name = name ?? "";
if (!input.CanSeek)
m_source = input;
m_should_dispose = !leave_open;
if (!m_source.CanSeek)
{
m_source = new MemoryStream();
input.CopyTo (m_source);
m_should_dispose = true;
if (!leave_open)
input.Dispose();
m_source.Position = 0;
m_buffer_end = m_source.Read (m_buffer, 0, 4);
if (4 == m_buffer_end)
{
uint signature = LittleEndian.ToUInt32 (m_buffer, 0);
m_signature = new Lazy<uint> (() => signature);
}
}
else
{
m_source = input;
m_should_dispose = !leave_open;
m_signature = new Lazy<uint> (ReadSignature);
}
}
@ -265,6 +288,8 @@ namespace GameRes
public CowArray<byte> ReadHeader (int size)
{
if (!CanSeek)
throw new NotSupportedException ("Unseekable stream");
if (m_header_size < size)
{
if (null == m_header || m_header.Length < size)
@ -272,7 +297,11 @@ namespace GameRes
Position = m_header_size;
m_header_size += Read (m_header, m_header_size, size - m_header_size);
}
size = Math.Min (size, m_header_size);
if (size > m_header_size)
{
Position = m_header_size;
throw new EndOfStreamException();
}
Position = size;
return new CowArray<byte> (m_header, 0, size);
}

View File

@ -63,7 +63,7 @@ namespace GameRes
public override ImageData Read (IBinaryStream file, ImageMetaData info)
{
var bmp_info = info as BmpMetaData;
if (bmp_info != null && EnableExtensions)
if (bmp_info != null && EnableExtensions && file.AsStream.CanSeek)
{
foreach (var ext in m_extensions)
{