From d0c1d5da01a4db0262901be5e68dc253e9f3606d Mon Sep 17 00:00:00 2001 From: morkt Date: Sat, 15 Oct 2016 12:21:12 +0400 Subject: [PATCH] IBinaryStream migration - continued. --- ArcFormats/Abel/ImageGPS.cs | 30 ++++--- ArcFormats/AdvSys/ImageGWD.cs | 15 ++-- ArcFormats/AliceSoft/ImageAJP.cs | 8 +- ArcFormats/AliceSoft/ImageDCF.cs | 81 ++++++++--------- ArcFormats/Ankh/AudioPCM.cs | 22 +++-- ArcFormats/Aoi/ImageAGF.cs | 140 ++++++++++++++--------------- ArcFormats/AudioVOC.cs | 29 +++--- ArcFormats/Banana/ImageGEC.cs | 22 +++-- ArcFormats/Bruns/AudioUM3.cs | 4 +- ArcFormats/Bruns/ImageEENC.cs | 44 ++++----- ArcFormats/CaramelBox/ImageFCB.cs | 31 +++---- ArcFormats/Circus/ArcCRM.cs | 4 +- ArcFormats/Circus/ImageCRX.cs | 44 ++++----- ArcFormats/Circus/ImageCRXD.cs | 43 +++++---- ArcFormats/Cmvs/AudioMV.cs | 16 ++-- ArcFormats/Cmvs/ImagePSB.cs | 25 +++--- ArcFormats/Cri/AudioADX.cs | 10 +-- ArcFormats/Cri/AudioHCA.cs | 4 +- ArcFormats/Cri/ImageSPC.cs | 16 ++-- ArcFormats/Cri/ImageXTX.cs | 10 +-- ArcFormats/Crowd/ImageGAX.cs | 14 +-- ArcFormats/Cyberworks/AudioTINK.cs | 7 +- ArcFormats/EmonEngine/ImageBMP.cs | 37 ++++---- ArcFormats/ImageMB.cs | 11 +-- ArcFormats/Ipac/AudioWST.cs | 2 +- ArcFormats/Ipac/ImageIES.cs | 16 ++-- ArcFormats/Ivory/AudioCTRK.cs | 6 +- ArcFormats/Ivory/ImageMMD.cs | 93 +++++++++---------- ArcFormats/Ivory/ImageMOE.cs | 8 +- ArcFormats/Ivory/ImageSG.cs | 34 +++---- ArcFormats/KScript/ImageKGP.cs | 26 +++--- ArcFormats/KScript/ImageKSL.cs | 17 ++-- ArcFormats/Leaf/AudioG.cs | 12 ++- ArcFormats/Leaf/AudioW.cs | 16 ++-- ArcFormats/Leaf/ImageLGF.cs | 14 ++- ArcFormats/Leaf/ImagePX.cs | 62 ++++++------- ArcFormats/elf/ImageGPH.cs | 71 +++++++-------- GameRes/BinaryStream.cs | 57 +++++++++--- GameRes/ImageBMP.cs | 2 +- 39 files changed, 529 insertions(+), 574 deletions(-) diff --git a/ArcFormats/Abel/ImageGPS.cs b/ArcFormats/Abel/ImageGPS.cs index aac4cd25..39a1649d 100644 --- a/ArcFormats/Abel/ImageGPS.cs +++ b/ArcFormats/Abel/ImageGPS.cs @@ -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) diff --git a/ArcFormats/AdvSys/ImageGWD.cs b/ArcFormats/AdvSys/ImageGWD.cs index f781428c..61548b04 100644 --- a/ArcFormats/AdvSys/ImageGWD.cs +++ b/ArcFormats/AdvSys/ImageGWD.cs @@ -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; diff --git a/ArcFormats/AliceSoft/ImageAJP.cs b/ArcFormats/AliceSoft/ImageAJP.cs index 5880ee0d..29fe53df 100644 --- a/ArcFormats/AliceSoft/ImageAJP.cs +++ b/ArcFormats/AliceSoft/ImageAJP.cs @@ -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; diff --git a/ArcFormats/AliceSoft/ImageDCF.cs b/ArcFormats/AliceSoft/ImageDCF.cs index 7560aa50..6c07b512 100644 --- a/ArcFormats/AliceSoft/ImageDCF.cs +++ b/ArcFormats/AliceSoft/ImageDCF.cs @@ -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 } diff --git a/ArcFormats/Ankh/AudioPCM.cs b/ArcFormats/Ankh/AudioPCM.cs index f839b714..a503e939 100644 --- a/ArcFormats/Ankh/AudioPCM.cs +++ b/ArcFormats/Ankh/AudioPCM.cs @@ -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; diff --git a/ArcFormats/Aoi/ImageAGF.cs b/ArcFormats/Aoi/ImageAGF.cs index fb957ba3..582a8cd0 100644 --- a/ArcFormats/Aoi/ImageAGF.cs +++ b/ArcFormats/Aoi/ImageAGF.cs @@ -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) diff --git a/ArcFormats/AudioVOC.cs b/ArcFormats/AudioVOC.cs index e6c436e2..a2a97199 100644 --- a/ArcFormats/AudioVOC.cs +++ b/ArcFormats/AudioVOC.cs @@ -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); } } diff --git a/ArcFormats/Banana/ImageGEC.cs b/ArcFormats/Banana/ImageGEC.cs index 941036b8..69065d2e 100644 --- a/ArcFormats/Banana/ImageGEC.cs +++ b/ArcFormats/Banana/ImageGEC.cs @@ -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); } diff --git a/ArcFormats/Bruns/AudioUM3.cs b/ArcFormats/Bruns/AudioUM3.cs index b4290377..d999b5cf 100644 --- a/ArcFormats/Bruns/AudioUM3.cs +++ b/ArcFormats/Bruns/AudioUM3.cs @@ -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)); } } diff --git a/ArcFormats/Bruns/ImageEENC.cs b/ArcFormats/Bruns/ImageEENC.cs index 1a5804cc..bf048a24 100644 --- a/ArcFormats/Bruns/ImageEENC.cs +++ b/ArcFormats/Bruns/ImageEENC.cs @@ -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 { diff --git a/ArcFormats/CaramelBox/ImageFCB.cs b/ArcFormats/CaramelBox/ImageFCB.cs index 7d6daebc..dac21673 100644 --- a/ArcFormats/CaramelBox/ImageFCB.cs +++ b/ArcFormats/CaramelBox/ImageFCB.cs @@ -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 diff --git a/ArcFormats/Circus/ArcCRM.cs b/ArcFormats/Circus/ArcCRM.cs index 96868c2d..026d16a3 100644 --- a/ArcFormats/Circus/ArcCRM.cs +++ b/ArcFormats/Circus/ArcCRM.cs @@ -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); } } diff --git a/ArcFormats/Circus/ImageCRX.cs b/ArcFormats/Circus/ImageCRX.cs index 22b28b02..4961b7e0 100644 --- a/ArcFormats/Circus/ImageCRX.cs +++ b/ArcFormats/Circus/ImageCRX.cs @@ -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 } diff --git a/ArcFormats/Circus/ImageCRXD.cs b/ArcFormats/Circus/ImageCRXD.cs index c4b1106e..a0ddb374 100644 --- a/ArcFormats/Circus/ImageCRXD.cs +++ b/ArcFormats/Circus/ImageCRXD.cs @@ -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) { diff --git a/ArcFormats/Cmvs/AudioMV.cs b/ArcFormats/Cmvs/AudioMV.cs index 57ce2873..643344f0 100644 --- a/ArcFormats/Cmvs/AudioMV.cs +++ b/ArcFormats/Cmvs/AudioMV.cs @@ -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 diff --git a/ArcFormats/Cmvs/ImagePSB.cs b/ArcFormats/Cmvs/ImagePSB.cs index db0d7a13..45821d4e 100644 --- a/ArcFormats/Cmvs/ImagePSB.cs +++ b/ArcFormats/Cmvs/ImagePSB.cs @@ -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); } diff --git a/ArcFormats/Cri/AudioADX.cs b/ArcFormats/Cri/AudioADX.cs index d2083054..dddacba8 100644 --- a/ArcFormats/Cri/AudioADX.cs +++ b/ArcFormats/Cri/AudioADX.cs @@ -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); } } diff --git a/ArcFormats/Cri/AudioHCA.cs b/ArcFormats/Cri/AudioHCA.cs index 2794483c..3461144c 100644 --- a/ArcFormats/Cri/AudioHCA.cs +++ b/ArcFormats/Cri/AudioHCA.cs @@ -49,9 +49,9 @@ namespace GameRes.Formats.Cri static readonly Tuple 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); } } diff --git a/ArcFormats/Cri/ImageSPC.cs b/ArcFormats/Cri/ImageSPC.cs index 06f42700..7f65e5dc 100644 --- a/ArcFormats/Cri/ImageSPC.cs +++ b/ArcFormats/Cri/ImageSPC.cs @@ -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) diff --git a/ArcFormats/Cri/ImageXTX.cs b/ArcFormats/Cri/ImageXTX.cs index a40848b7..e1acdd70 100644 --- a/ArcFormats/Cri/ImageXTX.cs +++ b/ArcFormats/Cri/ImageXTX.cs @@ -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); } diff --git a/ArcFormats/Crowd/ImageGAX.cs b/ArcFormats/Crowd/ImageGAX.cs index 4a12ea60..1d5aa19c 100644 --- a/ArcFormats/Crowd/ImageGAX.cs +++ b/ArcFormats/Crowd/ImageGAX.cs @@ -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); } diff --git a/ArcFormats/Cyberworks/AudioTINK.cs b/ArcFormats/Cyberworks/AudioTINK.cs index 4eba887f..6ea8ab2f 100644 --- a/ArcFormats/Cyberworks/AudioTINK.cs +++ b/ArcFormats/Cyberworks/AudioTINK.cs @@ -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; diff --git a/ArcFormats/EmonEngine/ImageBMP.cs b/ArcFormats/EmonEngine/ImageBMP.cs index 9487c9e3..c1d77cbe 100644 --- a/ArcFormats/EmonEngine/ImageBMP.cs +++ b/ArcFormats/EmonEngine/ImageBMP.cs @@ -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; diff --git a/ArcFormats/ImageMB.cs b/ArcFormats/ImageMB.cs index b388d0af..d1afc649 100644 --- a/ArcFormats/ImageMB.cs +++ b/ArcFormats/ImageMB.cs @@ -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) diff --git a/ArcFormats/Ipac/AudioWST.cs b/ArcFormats/Ipac/AudioWST.cs index be9272ab..6c52a55d 100644 --- a/ArcFormats/Ipac/AudioWST.cs +++ b/ArcFormats/Ipac/AudioWST.cs @@ -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; diff --git a/ArcFormats/Ipac/ImageIES.cs b/ArcFormats/Ipac/ImageIES.cs index b9d9749d..75e9a3c1 100644 --- a/ArcFormats/Ipac/ImageIES.cs +++ b/ArcFormats/Ipac/ImageIES.cs @@ -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(); diff --git a/ArcFormats/Ivory/AudioCTRK.cs b/ArcFormats/Ivory/AudioCTRK.cs index 2e8849b7..fb8a2acd 100644 --- a/ArcFormats/Ivory/AudioCTRK.cs +++ b/ArcFormats/Ivory/AudioCTRK.cs @@ -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); diff --git a/ArcFormats/Ivory/ImageMMD.cs b/ArcFormats/Ivory/ImageMMD.cs index 97de8fe7..8a0ef6e2 100644 --- a/ArcFormats/Ivory/ImageMMD.cs +++ b/ArcFormats/Ivory/ImageMMD.cs @@ -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); } diff --git a/ArcFormats/Ivory/ImageMOE.cs b/ArcFormats/Ivory/ImageMOE.cs index e51142de..e403563b 100644 --- a/ArcFormats/Ivory/ImageMOE.cs +++ b/ArcFormats/Ivory/ImageMOE.cs @@ -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]; diff --git a/ArcFormats/Ivory/ImageSG.cs b/ArcFormats/Ivory/ImageSG.cs index 42573347..a24a1d5b 100644 --- a/ArcFormats/Ivory/ImageSG.cs +++ b/ArcFormats/Ivory/ImageSG.cs @@ -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 } diff --git a/ArcFormats/KScript/ImageKGP.cs b/ArcFormats/KScript/ImageKGP.cs index d623db78..0580c968 100644 --- a/ArcFormats/KScript/ImageKGP.cs +++ b/ArcFormats/KScript/ImageKGP.cs @@ -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); } diff --git a/ArcFormats/KScript/ImageKSL.cs b/ArcFormats/KScript/ImageKSL.cs index 25e96d6c..dac83ec2 100644 --- a/ArcFormats/KScript/ImageKSL.cs +++ b/ArcFormats/KScript/ImageKSL.cs @@ -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); diff --git a/ArcFormats/Leaf/AudioG.cs b/ArcFormats/Leaf/AudioG.cs index b4cc999d..1a660943 100644 --- a/ArcFormats/Leaf/AudioG.cs +++ b/ArcFormats/Leaf/AudioG.cs @@ -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)); } } diff --git a/ArcFormats/Leaf/AudioW.cs b/ArcFormats/Leaf/AudioW.cs index 689bbb14..d0b35ce4 100644 --- a/ArcFormats/Leaf/AudioW.cs +++ b/ArcFormats/Leaf/AudioW.cs @@ -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); } } diff --git a/ArcFormats/Leaf/ImageLGF.cs b/ArcFormats/Leaf/ImageLGF.cs index f9576c18..914d527a 100644 --- a/ArcFormats/Leaf/ImageLGF.cs +++ b/ArcFormats/Leaf/ImageLGF.cs @@ -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 diff --git a/ArcFormats/Leaf/ImagePX.cs b/ArcFormats/Leaf/ImagePX.cs index 16f114c0..f7bf2637 100644 --- a/ArcFormats/Leaf/ImagePX.cs +++ b/ArcFormats/Leaf/ImagePX.cs @@ -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 } diff --git a/ArcFormats/elf/ImageGPH.cs b/ArcFormats/elf/ImageGPH.cs index c3d42dda..71246bee 100644 --- a/ArcFormats/elf/ImageGPH.cs +++ b/ArcFormats/elf/ImageGPH.cs @@ -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 } diff --git a/GameRes/BinaryStream.cs b/GameRes/BinaryStream.cs index a730e0d1..67238406 100644 --- a/GameRes/BinaryStream.cs +++ b/GameRes/BinaryStream.cs @@ -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 arr, int index, string str) + { + arr.Reclaim(); + return Binary.AsciiEqual (arr.ToArray(), index, str); + } + + public static bool AsciiEqual (this CowArray arr, string str) + { + arr.Reclaim(); + return Binary.AsciiEqual (arr.ToArray(), str); + } + + public static string GetCString (this CowArray 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 (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 (() => signature); + } } else { - m_source = input; - m_should_dispose = !leave_open; + m_signature = new Lazy (ReadSignature); } } @@ -265,6 +288,8 @@ namespace GameRes public CowArray 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 (m_header, 0, size); } diff --git a/GameRes/ImageBMP.cs b/GameRes/ImageBMP.cs index 6e2e74d6..09eff4b9 100644 --- a/GameRes/ImageBMP.cs +++ b/GameRes/ImageBMP.cs @@ -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) {