From a3729a11c7586466e9c610293e570c64a3390716 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 31 May 2013 20:10:51 +1200 Subject: [PATCH 1/7] Extract stream extensions to their own file. --- OpenRA.FileFormats/Exts.cs | 35 ------------ OpenRA.FileFormats/OpenRA.FileFormats.csproj | 1 + OpenRA.FileFormats/StreamExts.cs | 56 ++++++++++++++++++++ 3 files changed, 57 insertions(+), 35 deletions(-) create mode 100755 OpenRA.FileFormats/StreamExts.cs diff --git a/OpenRA.FileFormats/Exts.cs b/OpenRA.FileFormats/Exts.cs index f7e6c538aa..e58d62321c 100755 --- a/OpenRA.FileFormats/Exts.cs +++ b/OpenRA.FileFormats/Exts.cs @@ -41,41 +41,6 @@ namespace OpenRA return a.GetTypes().Select(t => t.Namespace).Distinct().Where(n => n != null); } - public static string ReadAllText(this Stream s) - { - using (s) - using (var sr = new StreamReader(s)) - return sr.ReadToEnd(); - } - - public static byte[] ReadAllBytes(this Stream s) - { - using (s) - { - var data = new byte[s.Length - s.Position]; - s.Read(data, 0, data.Length); - return data; - } - } - - public static void Write(this Stream s, byte[] data) - { - s.Write(data, 0, data.Length); - } - - public static IEnumerable ReadAllLines(this Stream s) - { - using (var sr = new StreamReader(s)) - for (; ; ) - { - var line = sr.ReadLine(); - if (line == null) - yield break; - else - yield return line; - } - } - public static bool HasAttribute(this MemberInfo mi) { return mi.GetCustomAttributes(typeof(T), true).Length != 0; diff --git a/OpenRA.FileFormats/OpenRA.FileFormats.csproj b/OpenRA.FileFormats/OpenRA.FileFormats.csproj index 57030eeb48..abe857a003 100644 --- a/OpenRA.FileFormats/OpenRA.FileFormats.csproj +++ b/OpenRA.FileFormats/OpenRA.FileFormats.csproj @@ -141,6 +141,7 @@ + diff --git a/OpenRA.FileFormats/StreamExts.cs b/OpenRA.FileFormats/StreamExts.cs new file mode 100755 index 0000000000..1d9c3bfe50 --- /dev/null +++ b/OpenRA.FileFormats/StreamExts.cs @@ -0,0 +1,56 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.IO; + +namespace OpenRA +{ + public static class StreamExts + { + public static string ReadAllText(this Stream s) + { + using (s) + using (var sr = new StreamReader(s)) + return sr.ReadToEnd(); + } + + public static byte[] ReadAllBytes(this Stream s) + { + using (s) + { + var data = new byte[s.Length - s.Position]; + s.Read(data, 0, data.Length); + return data; + } + } + + public static void Write(this Stream s, byte[] data) + { + s.Write(data, 0, data.Length); + } + + public static IEnumerable ReadAllLines(this Stream s) + { + using (var sr = new StreamReader(s)) + { + for (;;) + { + var line = sr.ReadLine(); + if (line == null) + yield break; + else + yield return line; + } + } + } + } +} From 93b606da2c4ce082dd619abc47b3bdcd2bb7629d Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 31 May 2013 19:32:59 +1200 Subject: [PATCH 2/7] Add stream extensions for reading basic types. --- OpenRA.FileFormats/StreamExts.cs | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/OpenRA.FileFormats/StreamExts.cs b/OpenRA.FileFormats/StreamExts.cs index 1d9c3bfe50..0604cc25f6 100755 --- a/OpenRA.FileFormats/StreamExts.cs +++ b/OpenRA.FileFormats/StreamExts.cs @@ -11,11 +11,74 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace OpenRA { public static class StreamExts { + public static byte[] ReadBytes(this Stream s, int count) + { + if (count < 0) + throw new ArgumentOutOfRangeException("count", "Non-negative number required."); + + var buf = new byte[count]; + if (s.Read(buf, 0, count) < count) + throw new EndOfStreamException(); + + return buf; + } + + public static int Peek(this Stream s) + { + var buf = new byte[1]; + if (s.Read(buf, 0, 1) == 0) + return -1; + + s.Seek(s.Position - 1, SeekOrigin.Begin); + return buf[0]; + } + + public static byte ReadUInt8(this Stream s) + { + return s.ReadBytes(1)[0]; + } + + public static ushort ReadUInt16(this Stream s) + { + return BitConverter.ToUInt16(s.ReadBytes(2), 0); + } + + public static short ReadInt16(this Stream s) + { + return BitConverter.ToInt16(s.ReadBytes(2), 0); + } + + public static uint ReadUInt32(this Stream s) + { + return BitConverter.ToUInt32(s.ReadBytes(4), 0); + } + + public static int ReadInt32(this Stream s) + { + return BitConverter.ToInt32(s.ReadBytes(4), 0); + } + + public static float ReadFloat(this Stream s) + { + return BitConverter.ToSingle(s.ReadBytes(4), 0); + } + + public static double ReadDouble(this Stream s) + { + return BitConverter.ToDouble(s.ReadBytes(8), 0); + } + + public static string ReadASCII(this Stream s, int length) + { + return new string(Encoding.ASCII.GetChars(s.ReadBytes(length))); + } + public static string ReadAllText(this Stream s) { using (s) From 6edde6c4acc742c5537c856815a66468406b47cc Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 31 May 2013 19:36:06 +1200 Subject: [PATCH 3/7] Remove BinaryReader from MixFile. --- OpenRA.FileFormats/Filesystem/MixFile.cs | 20 ++++++++------------ OpenRA.FileFormats/PackageEntry.cs | 8 ++++---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/OpenRA.FileFormats/Filesystem/MixFile.cs b/OpenRA.FileFormats/Filesystem/MixFile.cs index 2dff06dfaa..df041d8fc9 100644 --- a/OpenRA.FileFormats/Filesystem/MixFile.cs +++ b/OpenRA.FileFormats/Filesystem/MixFile.cs @@ -62,13 +62,12 @@ namespace OpenRA.FileFormats // Detect format type s.Seek(0, SeekOrigin.Begin); - var reader = new BinaryReader(s); - var isCncMix = reader.ReadUInt16() != 0; + var isCncMix = s.ReadUInt16() != 0; // The C&C mix format doesn't contain any flags or encryption var isEncrypted = false; if (!isCncMix) - isEncrypted = (reader.ReadUInt16() & 0x2) != 0; + isEncrypted = (s.ReadUInt16() & 0x2) != 0; List entries; if (isEncrypted) @@ -88,13 +87,12 @@ namespace OpenRA.FileFormats List ParseHeader(Stream s, long offset, out long headerEnd) { s.Seek(offset, SeekOrigin.Begin); - var reader = new BinaryReader(s); - var numFiles = reader.ReadUInt16(); - /*uint dataSize = */reader.ReadUInt32(); + var numFiles = s.ReadUInt16(); + /*uint dataSize = */s.ReadUInt32(); var items = new List(); for (var i = 0; i < numFiles; i++) - items.Add(new PackageEntry(reader)); + items.Add(new PackageEntry(s)); headerEnd = offset + 6 + numFiles*PackageEntry.Size; return items; @@ -103,16 +101,15 @@ namespace OpenRA.FileFormats MemoryStream DecryptHeader(Stream s, long offset, out long headerEnd) { s.Seek(offset, SeekOrigin.Begin); - var reader = new BinaryReader(s); // Decrypt blowfish key - var keyblock = reader.ReadBytes(80); + var keyblock = s.ReadBytes(80); var blowfishKey = new BlowfishKeyProvider().DecryptKey(keyblock); var fish = new Blowfish(blowfishKey); // Decrypt first block to work out the header length var ms = Decrypt(ReadBlocks(s, offset + 80, 1), fish); - var numFiles = new BinaryReader(ms).ReadUInt16(); + var numFiles = ms.ReadUInt16(); // Decrypt the full header - round bytes up to a full block var blockCount = (13 + numFiles*PackageEntry.Size)/8; @@ -138,12 +135,11 @@ namespace OpenRA.FileFormats uint[] ReadBlocks(Stream s, long offset, int count) { s.Seek(offset, SeekOrigin.Begin); - var r = new BinaryReader(s); // A block is a single encryption unit (represented as two 32-bit integers) var ret = new uint[2*count]; for (var i = 0; i < ret.Length; i++) - ret[i] = r.ReadUInt32(); + ret[i] = s.ReadUInt32(); return ret; } diff --git a/OpenRA.FileFormats/PackageEntry.cs b/OpenRA.FileFormats/PackageEntry.cs index 5839099838..0460f36cef 100644 --- a/OpenRA.FileFormats/PackageEntry.cs +++ b/OpenRA.FileFormats/PackageEntry.cs @@ -30,11 +30,11 @@ namespace OpenRA.FileFormats Length = length; } - public PackageEntry(BinaryReader r) + public PackageEntry(Stream s) { - Hash = r.ReadUInt32(); - Offset = r.ReadUInt32(); - Length = r.ReadUInt32(); + Hash = s.ReadUInt32(); + Offset = s.ReadUInt32(); + Length = s.ReadUInt32(); } public void Write(BinaryWriter w) From dd23e9598a6e2e3a81a3153fef88baf99c6777c6 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 31 May 2013 19:42:26 +1200 Subject: [PATCH 4/7] Remove BinaryReader from ShpTSReader. --- OpenRA.FileFormats/Graphics/ShpTSReader.cs | 53 +++++++++++----------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/OpenRA.FileFormats/Graphics/ShpTSReader.cs b/OpenRA.FileFormats/Graphics/ShpTSReader.cs index 62c4d2b56f..68cfbb918b 100644 --- a/OpenRA.FileFormats/Graphics/ShpTSReader.cs +++ b/OpenRA.FileFormats/Graphics/ShpTSReader.cs @@ -84,7 +84,7 @@ namespace OpenRA.FileFormats private readonly List headers = new List(); - public ShpTSReader(Stream stream) + public ShpTSReader(Stream s) { SHP SHP = new SHP(); @@ -100,13 +100,12 @@ namespace OpenRA.FileFormats byte cp; byte[] Databuffer; - BinaryReader sReader = new BinaryReader(stream); - FileSize = (int)sReader.BaseStream.Length; + FileSize = (int)s.Length; // Get Header - SHP.Header.A = sReader.ReadUInt16(); - SHP.Header.Width = sReader.ReadUInt16(); - SHP.Header.Height = sReader.ReadUInt16(); - SHP.Header.NumImages = sReader.ReadUInt16(); + SHP.Header.A = s.ReadUInt16(); + SHP.Header.Width = s.ReadUInt16(); + SHP.Header.Height = s.ReadUInt16(); + SHP.Header.NumImages = s.ReadUInt16(); SHP.Data = new SHPData[SHP.Header.NumImages + 1]; @@ -116,18 +115,18 @@ namespace OpenRA.FileFormats { SHP.Data[x].HeaderImage = new HeaderImage(); - SHP.Data[x].HeaderImage.x = sReader.ReadUInt16(); - SHP.Data[x].HeaderImage.y = sReader.ReadUInt16(); - SHP.Data[x].HeaderImage.cx = sReader.ReadUInt16(); - SHP.Data[x].HeaderImage.cy = sReader.ReadUInt16(); + SHP.Data[x].HeaderImage.x = s.ReadUInt16(); + SHP.Data[x].HeaderImage.y = s.ReadUInt16(); + SHP.Data[x].HeaderImage.cx = s.ReadUInt16(); + SHP.Data[x].HeaderImage.cy = s.ReadUInt16(); - SHP.Data[x].HeaderImage.compression = sReader.ReadByte(); - SHP.Data[x].HeaderImage.align = sReader.ReadBytes(3); - sReader.ReadInt32(); - SHP.Data[x].HeaderImage.zero = sReader.ReadByte(); - SHP.Data[x].HeaderImage.transparent = sReader.ReadBytes(3); + SHP.Data[x].HeaderImage.compression = s.ReadUInt8(); + SHP.Data[x].HeaderImage.align = s.ReadBytes(3); + s.ReadInt32(); + SHP.Data[x].HeaderImage.zero = s.ReadUInt8(); + SHP.Data[x].HeaderImage.transparent = s.ReadBytes(3); - SHP.Data[x].HeaderImage.offset = sReader.ReadInt32(); + SHP.Data[x].HeaderImage.offset = s.ReadInt32(); } @@ -166,8 +165,8 @@ namespace OpenRA.FileFormats Databuffer = new byte[ImageSize]; for (int i = 0; i < ImageSize; i++) { - sReader.BaseStream.Position = SHP.Data[x].HeaderImage.offset + i; - Databuffer[i] = sReader.ReadByte(); + s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin); + Databuffer[i] = s.ReadUInt8(); } SHP.Data[x].Databuffer = new byte[(SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy)]; Decode3(Databuffer, ref SHP.Data[x].Databuffer, SHP.Data[x].HeaderImage.cx, SHP.Data[x].HeaderImage.cy, ref FileSize); @@ -221,8 +220,8 @@ namespace OpenRA.FileFormats Databuffer = new byte[ImageSize]; for (int i = 0; i < ImageSize; i++) { - sReader.BaseStream.Position = SHP.Data[x].HeaderImage.offset + i; - Databuffer[i] = sReader.ReadByte(); + s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin); + Databuffer[i] = s.ReadUInt8(); } SHP.Data[x].Databuffer = new byte[((SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy))]; @@ -279,8 +278,8 @@ namespace OpenRA.FileFormats Databuffer = new byte[ImageSize]; for (int i = 0; i < ImageSize; i++) { - sReader.BaseStream.Position = SHP.Data[x].HeaderImage.offset + i; - Databuffer[i] = sReader.ReadByte(); + s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin); + Databuffer[i] = s.ReadUInt8(); } Decode2(Databuffer, ref SHP.Data[x].Databuffer, SHP.Data[x].HeaderImage.cx, SHP.Data[x].HeaderImage.cy, ref ImageSize); @@ -334,8 +333,8 @@ namespace OpenRA.FileFormats Databuffer = new byte[ImageSize]; for (int i = 0; i < ImageSize; i++) { - sReader.BaseStream.Position = SHP.Data[x].HeaderImage.offset + i; - Databuffer[i] = sReader.ReadByte(); + s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin); + Databuffer[i] = s.ReadUInt8(); } SHP.Data[x].Databuffer = new byte[((SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy))]; Decode2(Databuffer, ref SHP.Data[x].Databuffer, SHP.Data[x].HeaderImage.cx, SHP.Data[x].HeaderImage.cy, ref ImageSize); @@ -389,8 +388,8 @@ namespace OpenRA.FileFormats Databuffer = new byte[ImageSize]; for (int i = 0; i < ImageSize; i++) { - sReader.BaseStream.Position = SHP.Data[x].HeaderImage.offset + i; - Databuffer[i] = sReader.ReadByte(); + s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin); + Databuffer[i] = s.ReadUInt8(); } SHP.Data[x].Databuffer = new byte[(SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy)]; SHP.Data[x].Databuffer = Databuffer; From 6d8df80664ee892b58773bd07a58ec74bd6d0659 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 31 May 2013 19:46:33 +1200 Subject: [PATCH 5/7] Remove BinaryReader from Dune2ShpReader. --- OpenRA.FileFormats/Graphics/Dune2ShpReader.cs | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/OpenRA.FileFormats/Graphics/Dune2ShpReader.cs b/OpenRA.FileFormats/Graphics/Dune2ShpReader.cs index 12d1c7e5c8..3951a50458 100644 --- a/OpenRA.FileFormats/Graphics/Dune2ShpReader.cs +++ b/OpenRA.FileFormats/Graphics/Dune2ShpReader.cs @@ -36,23 +36,23 @@ namespace OpenRA.FileFormats public readonly byte[] LookupTable; public byte[] Image; - public Dune2ImageHeader(BinaryReader reader) + public Dune2ImageHeader(Stream s) { - Flags = (Dune2ImageFlags)reader.ReadUInt16(); - Slices = reader.ReadByte(); - Width = reader.ReadUInt16(); - Height = reader.ReadByte(); - FileSize = reader.ReadUInt16(); - DataSize = reader.ReadUInt16(); + Flags = (Dune2ImageFlags)s.ReadUInt16(); + Slices = s.ReadUInt8(); + Width = s.ReadUInt16(); + Height = s.ReadUInt8(); + FileSize = s.ReadUInt16(); + DataSize = s.ReadUInt16(); if (Flags == Dune2ImageFlags.L16_F80_F2_1 || Flags == Dune2ImageFlags.L16_F80_F2_2 || Flags == Dune2ImageFlags.Ln_F80_F2) { - int n = Flags == Dune2ImageFlags.Ln_F80_F2 ? reader.ReadByte() : (byte)16; + int n = Flags == Dune2ImageFlags.Ln_F80_F2 ? s.ReadUInt8() : (byte)16; LookupTable = new byte[n]; for (int i = 0; i < n; i++) - LookupTable[i] = reader.ReadByte(); + LookupTable[i] = s.ReadUInt8(); } else { @@ -78,16 +78,14 @@ namespace OpenRA.FileFormats List headers = new List(); - public Dune2ShpReader(Stream stream) + public Dune2ShpReader(Stream s) { - BinaryReader reader = new BinaryReader(stream); - - ImageCount = reader.ReadUInt16(); + ImageCount = s.ReadUInt16(); //Last offset is pointer to end of file. uint[] offsets = new uint[ImageCount + 1]; - uint temp = reader.ReadUInt32(); + uint temp = s.ReadUInt32(); //If fourth byte in file is non-zero, the offsets are two bytes each. bool twoByteOffsets = (temp & 0xFF0000) > 0; @@ -100,13 +98,13 @@ namespace OpenRA.FileFormats offsets[0] = temp + 2; for (int i = twoByteOffsets ? 2 : 1; i < ImageCount + 1; i++) - offsets[i] = (twoByteOffsets ? reader.ReadUInt16() : reader.ReadUInt32()) + 2; + offsets[i] = (twoByteOffsets ? s.ReadUInt16() : s.ReadUInt32()) + 2; for (int i = 0; i < ImageCount; i++) { - reader.BaseStream.Seek(offsets[i], SeekOrigin.Begin); - Dune2ImageHeader header = new Dune2ImageHeader(reader); - byte[] imgData = reader.ReadBytes(header.FileSize); + s.Seek(offsets[i], SeekOrigin.Begin); + Dune2ImageHeader header = new Dune2ImageHeader(s); + byte[] imgData = s.ReadBytes(header.FileSize); header.Image = new byte[header.Height * header.Width]; //Decode image data From edf604e080645013ce77a25ef0d340e9ddcf7930 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 31 May 2013 20:01:10 +1200 Subject: [PATCH 6/7] Remove BinaryReader from VqaReader. --- OpenRA.FileFormats/Graphics/VqaReader.cs | 118 +++++++++++------------ 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/OpenRA.FileFormats/Graphics/VqaReader.cs b/OpenRA.FileFormats/Graphics/VqaReader.cs index 66db6c788f..7c9b94025e 100644 --- a/OpenRA.FileFormats/Graphics/VqaReader.cs +++ b/OpenRA.FileFormats/Graphics/VqaReader.cs @@ -46,67 +46,66 @@ namespace OpenRA.FileFormats public byte[] AudioData { get { return audioData; } } public int CurrentFrame { get { return currentFrame; } } - public VqaReader( Stream stream ) + public VqaReader(Stream stream) { this.stream = stream; - BinaryReader reader = new BinaryReader( stream ); // Decode FORM chunk - if (new String(reader.ReadChars(4)) != "FORM") + if (stream.ReadASCII(4) != "FORM") throw new InvalidDataException("Invalid vqa (invalid FORM section)"); - /*var length = */ reader.ReadUInt32(); + /*var length = */ stream.ReadUInt32(); - if (new String(reader.ReadChars(8)) != "WVQAVQHD") + if (stream.ReadASCII(8) != "WVQAVQHD") throw new InvalidDataException("Invalid vqa (not WVQAVQHD)"); - /* var length = */reader.ReadUInt32(); + /* var length = */stream.ReadUInt32(); - /*var version = */reader.ReadUInt16(); - /*var flags = */reader.ReadUInt16(); - Frames = reader.ReadUInt16(); - Width = reader.ReadUInt16(); - Height = reader.ReadUInt16(); + /*var version = */stream.ReadUInt16(); + /*var flags = */stream.ReadUInt16(); + Frames = stream.ReadUInt16(); + Width = stream.ReadUInt16(); + Height = stream.ReadUInt16(); - blockWidth = reader.ReadByte(); - blockHeight = reader.ReadByte(); - Framerate = reader.ReadByte(); - cbParts = reader.ReadByte(); + blockWidth = stream.ReadUInt8(); + blockHeight = stream.ReadUInt8(); + Framerate = stream.ReadUInt8(); + cbParts = stream.ReadUInt8(); blocks = new int2(Width / blockWidth, Height / blockHeight); - numColors = reader.ReadUInt16(); - /*var maxBlocks = */reader.ReadUInt16(); - /*var unknown1 = */reader.ReadUInt16(); - /*var unknown2 = */reader.ReadUInt32(); + numColors = stream.ReadUInt16(); + /*var maxBlocks = */stream.ReadUInt16(); + /*var unknown1 = */stream.ReadUInt16(); + /*var unknown2 = */stream.ReadUInt32(); // Audio - /*var freq = */reader.ReadUInt16(); - /*var channels = */reader.ReadByte(); - /*var bits = */reader.ReadByte(); - /*var unknown3 = */reader.ReadChars(14); + /*var freq = */stream.ReadUInt16(); + /*var channels = */stream.ReadByte(); + /*var bits = */stream.ReadByte(); + /*var unknown3 = */stream.ReadBytes(14); - - var frameSize = Exts.NextPowerOf2(Math.Max(Width,Height)); + var frameSize = Exts.NextPowerOf2(Math.Max(Width, Height)); cbf = new byte[Width*Height]; cbp = new byte[Width*Height]; palette = new uint[numColors]; origData = new byte[2*blocks.X*blocks.Y]; - frameData = new uint[frameSize,frameSize]; + frameData = new uint[frameSize, frameSize]; - var type = new String(reader.ReadChars(4)); + var type = stream.ReadASCII(4); if (type != "FINF") { - reader.ReadBytes(27); - type = new String(reader.ReadChars(4)); + stream.Seek(27, SeekOrigin.Current); + type = stream.ReadASCII(4); } - /*var length = */reader.ReadUInt16(); - /*var unknown4 = */reader.ReadUInt16(); + /*var length = */stream.ReadUInt16(); + /*var unknown4 = */stream.ReadUInt16(); // Frame offsets offsets = new UInt32[Frames]; for (int i = 0; i < Frames; i++) { - offsets[i] = reader.ReadUInt32(); - if (offsets[i] > 0x40000000) offsets[i] -= 0x40000000; + offsets[i] = stream.ReadUInt32(); + if (offsets[i] > 0x40000000) + offsets[i] -= 0x40000000; offsets[i] <<= 1; } @@ -130,28 +129,28 @@ namespace OpenRA.FileFormats for (var i = 0; i < Frames; i++) { stream.Seek(offsets[i], SeekOrigin.Begin); - BinaryReader reader = new BinaryReader(stream); var end = (i < Frames - 1) ? offsets[i + 1] : stream.Length; - while (reader.BaseStream.Position < end) + while (stream.Position < end) { - var type = new String(reader.ReadChars(4)); - var length = int2.Swap(reader.ReadUInt32()); + var type = stream.ReadASCII(4); + var length = int2.Swap(stream.ReadUInt32()); switch (type) { case "SND0": case "SND2": - var rawAudio = reader.ReadBytes((int)length); + var rawAudio = stream.ReadBytes((int)length); ms.Write(rawAudio); compressed = (type == "SND2"); break; default: - reader.ReadBytes((int)length); + stream.ReadBytes((int)length); break; } - if (reader.PeekChar() == 0) reader.ReadByte(); + // Chunks are aligned on even bytes; advance by a byte if the next one is null + if (stream.Peek() == 0) stream.ReadByte(); } } @@ -171,48 +170,47 @@ namespace OpenRA.FileFormats // Seek to the start of the frame stream.Seek(offsets[currentFrame], SeekOrigin.Begin); - BinaryReader reader = new BinaryReader(stream); var end = (currentFrame < Frames - 1) ? offsets[currentFrame+1] : stream.Length; - while(reader.BaseStream.Position < end) + while (stream.Position < end) { - var type = new String(reader.ReadChars(4)); - var length = int2.Swap(reader.ReadUInt32()); + var type = stream.ReadASCII(4); + var length = int2.Swap(stream.ReadUInt32()); switch(type) { case "VQFR": - DecodeVQFR(reader); + DecodeVQFR(stream); break; default: // Don't parse sound here. - reader.ReadBytes((int)length); + stream.ReadBytes((int)length); break; } // Chunks are aligned on even bytes; advance by a byte if the next one is null - if (reader.PeekChar() == 0) reader.ReadByte(); + if (stream.Peek() == 0) stream.ReadByte(); } } // VQA Frame - public void DecodeVQFR(BinaryReader reader) + public void DecodeVQFR(Stream s) { - while(true) + while (true) { // Chunks are aligned on even bytes; may be padded with a single null - if (reader.PeekChar() == 0) reader.ReadByte(); - var type = new String(reader.ReadChars(4)); - int subchunkLength = (int)int2.Swap(reader.ReadUInt32()); + if (s.Peek() == 0) s.ReadByte(); + var type = s.ReadASCII(4); + int subchunkLength = (int)int2.Swap(s.ReadUInt32()); switch(type) { // Full frame-modifier case "CBFZ": - Format80.DecodeInto( reader.ReadBytes(subchunkLength), cbf ); + Format80.DecodeInto(s.ReadBytes(subchunkLength), cbf); break; case "CBF0": - cbf = reader.ReadBytes(subchunkLength); + cbf = s.ReadBytes(subchunkLength); break; // frame-modifier chunk @@ -224,12 +222,12 @@ namespace OpenRA.FileFormats if (type == "CBP0") cbf = (byte[])cbp.Clone(); else - Format80.DecodeInto( cbp, cbf ); + Format80.DecodeInto(cbp, cbf); cbOffset = cbChunk = 0; } - var bytes = reader.ReadBytes(subchunkLength); + var bytes = s.ReadBytes(subchunkLength); bytes.CopyTo(cbp,cbOffset); cbOffset += subchunkLength; cbChunk++; @@ -239,16 +237,16 @@ namespace OpenRA.FileFormats case "CPL0": for (int i = 0; i < numColors; i++) { - byte r = (byte)(reader.ReadByte() << 2); - byte g = (byte)(reader.ReadByte() << 2); - byte b = (byte)(reader.ReadByte() << 2); + byte r = (byte)(s.ReadUInt8() << 2); + byte g = (byte)(s.ReadUInt8() << 2); + byte b = (byte)(s.ReadUInt8() << 2); palette[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b); } break; // Frame data case "VPTZ": - Format80.DecodeInto( reader.ReadBytes(subchunkLength), origData ); + Format80.DecodeInto(s.ReadBytes(subchunkLength), origData); // This is the last subchunk return; default: From 61c5b99dc547414c3ff7f77ed681bd3211ae16ba Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 31 May 2013 20:06:35 +1200 Subject: [PATCH 7/7] Remove BinaryReader from R8Reader. --- OpenRA.Utility/R8Reader.cs | 54 ++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/OpenRA.Utility/R8Reader.cs b/OpenRA.Utility/R8Reader.cs index f71f9aa76c..7f9b1d0462 100644 --- a/OpenRA.Utility/R8Reader.cs +++ b/OpenRA.Utility/R8Reader.cs @@ -34,22 +34,22 @@ namespace OpenRA.Utility public int OffsetX; public int OffsetY; - public R8Image(BinaryReader reader, int Frame) + public R8Image(Stream s, int Frame) { - var offset = reader.BaseStream.Position; - var ID = reader.ReadByte(); // 0 = no data, 1 = picture with palette, 2 = picture with current palette + var offset = s.Position; + var ID = s.ReadUInt8(); // 0 = no data, 1 = picture with palette, 2 = picture with current palette while (ID == 0) - ID = reader.ReadByte(); - Width = reader.ReadInt32(); //Width of picture - Height = reader.ReadInt32(); //Height of picture - OffsetX = reader.ReadInt32(); //Offset on X axis from left border edge of virtual frame - OffsetY = reader.ReadInt32(); //Offset on Y axis from top border edge of virtual frame - ImageHandle = reader.ReadInt32(); // 0 = no picture - PaletteHandle = reader.ReadInt32(); // 0 = no palette - var Bpp = reader.ReadByte(); // Bits per Pixel - FrameHeight = reader.ReadByte(); // Height of virtual frame - FrameWidth = reader.ReadByte(); // Width of virtual frame - var Align = reader.ReadByte(); //Alignment on even border + ID = s.ReadUInt8(); + Width = s.ReadInt32(); //Width of picture + Height = s.ReadInt32(); //Height of picture + OffsetX = s.ReadInt32(); //Offset on X axis from left border edge of virtual frame + OffsetY = s.ReadInt32(); //Offset on Y axis from top border edge of virtual frame + ImageHandle = s.ReadInt32(); // 0 = no picture + PaletteHandle = s.ReadInt32(); // 0 = no palette + var Bpp = s.ReadUInt8(); // Bits per Pixel + FrameHeight = s.ReadUInt8(); // Height of virtual frame + FrameWidth = s.ReadUInt8(); // Width of virtual frame + var Align = s.ReadUInt8(); //Alignment on even border Console.WriteLine("Offset: {0}",offset); Console.WriteLine("ID: {0}",ID); @@ -74,23 +74,23 @@ namespace OpenRA.Utility if (ID == 1 && PaletteHandle != 0) { // read and ignore custom palette - reader.ReadInt32(); //Memory - reader.ReadInt32(); //Handle + s.ReadInt32(); //Memory + s.ReadInt32(); //Handle for (int i = 0; i < Width*Height; i++) - Image[i] = reader.ReadByte(); + Image[i] = s.ReadUInt8(); for (int i = 0; i < 256; i++) - reader.ReadUInt16(); + s.ReadUInt16(); } else if (ID == 2 && PaletteHandle != 0) // image with custom palette { for (int i = 0; i < Width*Height; i++) - Image[i] = reader.ReadByte(); + Image[i] = s.ReadUInt8(); } else //standard palette or 16 Bpp { for (int i = 0; i < Width*Height; i++) - Image[i] = reader.ReadByte(); + Image[i] = s.ReadUInt8(); } } } @@ -100,17 +100,15 @@ namespace OpenRA.Utility private readonly List headers = new List(); public readonly int Frames; - public R8Reader( Stream stream ) + public R8Reader(Stream stream) { - BinaryReader reader = new BinaryReader( stream ); - Frames = 0; - while (reader.BaseStream.Position < stream.Length) + while (stream.Position < stream.Length) { try { - Console.WriteLine("Frame {0}: {1}",Frames, reader.BaseStream.Position); - headers.Add( new R8Image( reader, Frames ) ); + Console.WriteLine("Frame {0}: {1}",Frames, stream.Position); + headers.Add(new R8Image(stream, Frames)); Frames++; } catch (Exception e) @@ -121,9 +119,9 @@ namespace OpenRA.Utility } } - public R8Image this[ int index ] + public R8Image this[int index] { - get { return headers[ index ]; } + get { return headers[index]; } } public IEnumerator GetEnumerator()