public MemoryStream Read(Stream input, DataDefinition data) { switch (data.Type.CompressionMode) { case CompressionMode.CompressedPerType: { var buffer = this.GetType(input, data.Type); buffer.Seek(data.Offset, SeekOrigin.Begin); return(buffer.ReadToMemoryStream(data.UncompressedSize)); } case CompressionMode.CompressedPerResource: { input.Seek(data.Type.Offset, SeekOrigin.Begin); input.Seek(data.Offset, SeekOrigin.Current); var zlib = new InflaterInputStream(input); return(zlib.ReadToMemoryStream(data.UncompressedSize)); } default: { throw new NotImplementedException(); } } }
protected MemoryStream GetType(Stream input, TypeDefinition type) { if (this.LoadedTypes.ContainsKey(type) == false) { input.Seek(type.Offset, SeekOrigin.Begin); var zlib = new InflaterInputStream(input); this.LoadedTypes[type] = zlib.ReadToMemoryStream(type.UncompressedSize); } return(this.LoadedTypes[type]); }
public static MemoryStream Decompress(Stream input) { var dcx = new CompressedFile(); dcx.Deserialize(input); if (dcx._Setup.Scheme == CompressionScheme.Zlib) { if (dcx._Setup.Unknown1C != 0 || dcx._Setup.Unknown20 != 0 || dcx._Setup.Unknown24 != 0 || dcx._Setup.Flags != 0x00010100) { throw new FormatException(); } using (var temp = input.ReadToMemoryStream(dcx._Size.CompressedSize)) { var zlib = new InflaterInputStream(temp); return(zlib.ReadToMemoryStream(dcx._Size.UncompressedSize)); } } else if (dcx._Setup.Scheme == CompressionScheme.Edge) { if (dcx._Setup.Unknown1C != 0x00010000 || dcx._Setup.Unknown20 != 0 || dcx._Setup.Unknown24 != 0 || dcx._Setup.Flags != 0x00100100) { throw new FormatException(); } using (var table = new MemoryStream(dcx._Extra.Data)) { if (table.ReadValueU32(Endian.Big) != 0x45676454) // EdgT = Edge Table? { throw new FormatException(); } var unknown04 = table.ReadValueU32(Endian.Big); var tableOffset = table.ReadValueU32(Endian.Big); var alignment = table.ReadValueU32(Endian.Big); var uncompressedBlockSize = table.ReadValueU32(Endian.Big); var finalUncompressedBlockSize = table.ReadValueU32(Endian.Big); var extraSize = table.ReadValueU32(Endian.Big); var blockCount = table.ReadValueU32(Endian.Big); var unknown20 = table.ReadValueU32(Endian.Big); if (extraSize != table.Length) { throw new FormatException(); } if (unknown04 != 0x00010100 || tableOffset != 36 || alignment != 16 || uncompressedBlockSize != 0x00010000 || unknown20 != 0x00100000) { throw new FormatException(); } var data = new MemoryStream(); for (uint i = 0; i < blockCount; i++) { var bunknown0 = table.ReadValueU32(Endian.Big); var blockOffset = table.ReadValueU32(Endian.Big); var blockSize = table.ReadValueU32(Endian.Big); var blockFlags = table.ReadValueU32(Endian.Big); if (bunknown0 != 0 || (blockFlags != 0 && blockFlags != 1)) { throw new FormatException(); } using (var temp = input.ReadToMemoryStream(blockSize.Align(alignment))) { if (blockFlags == 1) { var zlib = new InflaterInputStream(temp, new Inflater(true)); data.WriteFromStream(zlib, i + 1 < blockCount ? uncompressedBlockSize : finalUncompressedBlockSize); } else if (blockFlags == 0) { data.WriteFromStream(temp, i + 1 < blockCount ? uncompressedBlockSize : finalUncompressedBlockSize); } else { throw new NotImplementedException(); } } } if (data.Length != dcx._Size.UncompressedSize) { throw new InvalidOperationException(); } data.Position = 0; return(data); } } else { throw new NotImplementedException(); } }