/// <summary> /// Constructor; parses MAS2 file for its contents. /// Use the ContainsFile & GetFile methods to search for files. /// Use the ExctractFile, ExctractString and ExtractBytes methods /// for extracting a file. /// </summary> /// <param name="file"></param> public MAS2Reader(string file) { _File = file; Reader = new BinaryReader(System.IO.File.OpenRead(file)); ReadHeader(); var filePosition = (ulong)Reader.BaseStream.Position; Reader.Close(); // number of files var files = BitConverter.ToUInt64(FileHeader, 4); var headerOffset = 12; for (var i = 0; i < (int)files; i++) { var offset = i * 256 + headerOffset; var fileType = BitConverter.ToUInt32(FileHeader, offset); var filename = Encoding.ASCII.GetString(FileHeader, offset + 4, 228); filename = filename.Substring(0, filename.IndexOf('\0')); var dataOffset = BitConverter.ToUInt64(FileHeader, offset + 29 * 8); var sizeUncompressed = BitConverter.ToUInt64(FileHeader, offset + 30 * 8); var sizeCompressed = BitConverter.ToUInt64(FileHeader, offset + 31 * 8); var masfile = new MAS2File((uint)i, fileType, filename, sizeCompressed, sizeUncompressed, filePosition + dataOffset); _files.Add(masfile); } }
public string ExtractString(MAS2File f) { return Encoding.ASCII.GetString(ExtractBytes(f)); }
public void ExtractFile(MAS2File f, string target) { System.IO.File.WriteAllBytes(target, ExtractBytes(f)); }
public byte[] ExtractBytes(MAS2File f) { var reader = new BinaryReader(System.IO.File.OpenRead(this._File)); reader.BaseStream.Seek((long)f.FileOffset, SeekOrigin.Begin); var rawData = reader.ReadBytes((int)f.CompressedSize); reader.Close(); if (!f.IsCompressed) { return rawData; } // ISI GMotor2 compressed if ((f.FileType & 0x10000) != 0 && rawData[0] >= 0x03 && rawData[0] < 0x20) { var outputData = new byte[f.UncompressedSize]; MAS2Codec.Decode(rawData, outputData); return outputData; } // ZLIB deflate if ((f.FileType & 0x10) != 0) { var outputData = new byte[f.UncompressedSize]; // strip 2-byte header and 4-byte adler32 checksum from tail using (var compressedStream = new MemoryStream(rawData, 2, rawData.Length - 6)) using (var decompress = new DeflateStream(compressedStream, CompressionMode.Decompress)) { int read = decompress.Read(outputData, 0, outputData.Length); if (read != outputData.Length) { throw new System.Exception(string.Format("Uncompressed size does not match ({0}!={1})", read, outputData.Length)); } } //return outputStream.ToArray(); return outputData; } throw new System.Exception(String.Format("Unkown encoding type {0}", f.FileType)); }
/// <summary> /// Constructor; parses MAS2 file for its contents. /// Use the ContainsFile & GetFile methods to search for files. /// Use the ExctractFile, ExctractString and ExtractBytes methods /// for extracting a file. /// </summary> /// <param name="file"></param> public MAS2Reader(string file) { _File = file; Reader = new BinaryReader(System.IO.File.OpenRead(file)); ReadHeader(); var files = FileHeader.Length / 256; var filePosition = (uint)Reader.BaseStream.Position; Reader.Close(); for (var i = 0; i < files; i++) { var filename = Encoding.ASCII.GetString(FileHeader, i * 256 + 16, 128); filename = filename.Substring(0, filename.IndexOf('\0')); var path = Encoding.ASCII.GetString(FileHeader, i * 256 + 16 + filename.Length + 1, 128); path = path.Substring(0, path.IndexOf('\0')); var fileIndex = BitConverter.ToUInt32(FileHeader, i * 256); var sizeCompressed = BitConverter.ToUInt32(FileHeader, 65*4 + i * 256); var sizeUncompressed = BitConverter.ToUInt32(FileHeader, 63 * 4 + i * 256); var masfile = new MAS2File(fileIndex, filename, path, sizeCompressed, sizeUncompressed, filePosition); _files.Add(masfile); filePosition += sizeCompressed; } }
public void ExtractFile(MAS2File f, string target) { var reader = new BinaryReader(System.IO.File.OpenRead(_File)); reader.BaseStream.Seek(f.FileOffset, SeekOrigin.Begin); var rawData = reader.ReadBytes((int)f.CompressedSize); if (f.IsCompressed) { var outputData = new byte[f.UncompressedSize]; // MAS2 compression consists of a simple inflate/deflate action. var codec = new ZlibCodec(CompressionMode.Decompress); codec.InitializeInflate(); codec.InputBuffer = rawData; codec.NextIn = 0; codec.AvailableBytesIn = rawData.Length; codec.OutputBuffer = outputData; codec.NextOut = 0; codec.AvailableBytesOut = outputData.Length; codec.Inflate(FlushType.None); codec.EndInflate(); System.IO.File.WriteAllBytes(target, outputData); } else { System.IO.File.WriteAllBytes(target, rawData); } }