internal byte[] GetRawData() { bsa.br.BaseStream.Seek(offset, SeekOrigin.Begin); if (bsa.SkipNames) { bsa.br.BaseStream.Position += bsa.br.ReadByte() + 1; } if (compressed) { var b = new byte[size - 4]; var output = new byte[bsa.br.ReadUInt32()]; bsa.br.Read(b, 0, size - 4); var inf = new Inflater(); inf.SetInput(b, 0, b.Length); inf.Inflate(output); return output; } return bsa.br.ReadBytes(size); }
public static void Trim(IntPtr hwnd, string In, string Out, ReportProgressDelegate del) { NativeMethods.ddsInit(hwnd); var br = new BinaryReader(File.OpenRead(In), Encoding.Default); var bw = new BinaryWriter(File.Create(Out), Encoding.Default); var sb = new StringBuilder(64); var inf = new Inflater(); bool Compressed, SkipName; if (br.ReadInt32() != 0x00415342) { throw new Exception("Invalid bsa"); } var version = br.ReadUInt32(); bw.Write(0x00415342); bw.Write(version); bw.Write(br.ReadInt32()); var flags = br.ReadUInt32(); if ((flags & 0x004) > 0) { Compressed = true; flags ^= 0x4; } else { Compressed = false; } if ((flags & 0x100) > 0 && version == 0x68) { SkipName = true; } else { SkipName = false; } flags ^= 0x2; var FolderCount = br.ReadInt32(); var FileCount = br.ReadInt32(); bw.Write(flags); bw.Write(FolderCount); bw.Write(FileCount); bw.Write(br.ReadInt32()); bw.Write(br.ReadInt32()); bw.Write(br.ReadInt32()); var folderFileCount = new int[FolderCount]; for (var i = 0; i < FolderCount; i++) { bw.Write(br.ReadInt64()); folderFileCount[i] = br.ReadInt32(); bw.Write(folderFileCount[i]); bw.Write(br.ReadInt32()); } var fileLengths = new int[FileCount]; var offsetOffsets = new long[FileCount]; var fileOffsets = new uint[FileCount]; var parsefiles = new bool[FileCount]; var file = 0; for (var i = 0; i < FolderCount; i++) { var len = br.ReadByte(); bw.Write(len); sb.Length = 0; while (--len > 0) { var c = br.ReadChar(); sb.Append(c); bw.Write(c); } br.ReadByte(); bw.Write((byte) 0); var parse = true; if (sb.ToString().StartsWith("textures\\interface\\")) { parse = false; } for (var j = 0; j < folderFileCount[i]; j++) { bw.Write(br.ReadUInt64()); offsetOffsets[file] = br.BaseStream.Position; fileLengths[file] = br.ReadInt32(); bw.Write(fileLengths[file]); fileOffsets[file] = br.ReadUInt32(); bw.Write(fileOffsets[file]); parsefiles[file] = parse; file++; } } for (var i = 0; i < FileCount; i++) { sb.Length = 0; while (true) { var c = (char) br.ReadByte(); //bw.Write(c); if (c == '\0') { break; } sb.Append(c); } if (!sb.ToString().EndsWith(".dds", StringComparison.OrdinalIgnoreCase)) { parsefiles[i] = false; } } for (var i = 0; i < FileCount; i++) { if ((i%100) == 0) { del("Processing file " + i + " of " + FileCount); } br.BaseStream.Position = fileOffsets[i]; var offset = bw.BaseStream.Position; var add = 0; if (SkipName) { var len = br.ReadByte(); bw.Write(len); bw.Write(br.ReadBytes(len + 1)); add = len + 2; } var compressed2 = Compressed; if ((fileLengths[i] & (1 << 30)) != 0) { compressed2 = !compressed2; fileLengths[i] ^= (1 << 30); } if (!compressed2) { var bytes = new byte[fileLengths[i]]; br.Read(bytes, 0, fileLengths[i]); Commit(bw, offsetOffsets[i], bytes, offset, add, parsefiles[i]); } else { var uncompressed = new byte[br.ReadUInt32()]; var compressed = new byte[fileLengths[i] - 4]; br.Read(compressed, 0, fileLengths[i] - 4); inf.Reset(); inf.SetInput(compressed); inf.Inflate(uncompressed); Commit(bw, offsetOffsets[i], uncompressed, offset, add, parsefiles[i]); } } br.Close(); bw.Close(); NativeMethods.ddsClose(); }