public void Read(byte[] file) { FileInput f = new FileInput(file); f.byteOrder = byteOrder; f.Seek(8); // SARC+Endianness int archiveSize = f.ReadInt(); int startOffset = f.ReadInt(); padding = startOffset; f.Skip(10); // SFAT int nodeCount = f.ReadShort(); int hashMultiplier = f.ReadInt(); List <SFATNode> sfatNodes = new List <SFATNode>(); for (int i = 0; i < nodeCount; i++) { SFATNode temp; temp.nameHash = f.ReadInt(); temp.nameTableOffset = f.ReadInt() - 0x1000000; if (temp.nameTableOffset == -0x1000000) { temp.hasString = false; } else { temp.hasString = true; } temp.fileDataOffset = f.ReadInt(); temp.endFileDataOffset = f.ReadInt(); sfatNodes.Add(temp); } f.Skip(8); int nameTableStart = f.Position(); foreach (SFATNode sfat in sfatNodes) { string tempName; if (sfat.hasString) { f.Seek(sfat.nameTableOffset * 4 + nameTableStart); tempName = f.ReadString(); } else { tempName = "0x" + sfat.nameHash.ToString("X8"); } f.Seek(sfat.fileDataOffset + startOffset); byte[] tempFile = f.Read(sfat.endFileDataOffset - sfat.fileDataOffset); files.Add(tempName, tempFile); } }
public static byte[] Decompress(byte[] data) { FileInput f = new FileInput(data); f.byteOrder = ByteOrder.BigEndian; f.Seek(4); int uncompressedSize = f.ReadInt(); byte[] flags = f.Read(8); byte[] src = f.Read(data.Length - 0x10); byte[] dst = new byte[uncompressedSize]; int srcPlace = 0, dstPlace = 0; // Current read/write positions uint validBitCount = 0; // Number of valid bits left in "code" byte byte currCodeByte = 0; while (dstPlace < uncompressedSize) { // Read new "code" byte if the current one is used up if (validBitCount == 0) { currCodeByte = src[srcPlace]; ++srcPlace; validBitCount = 8; } if ((currCodeByte & 0x80) != 0) { // Straight copy dst[dstPlace] = src[srcPlace]; dstPlace++; srcPlace++; } else { // RLE part byte byte1 = src[srcPlace]; byte byte2 = src[srcPlace + 1]; srcPlace += 2; uint dist = (uint)(((byte1 & 0xF) << 8) | byte2); uint copySource = (uint)(dstPlace - (dist + 1)); uint numBytes = (uint)(byte1 >> 4); if (numBytes == 0) { numBytes = (uint)(src[srcPlace] + 0x12); srcPlace++; } else { numBytes += 2; } // Copy run for (int i = 0; i < numBytes; ++i) { dst[dstPlace] = dst[copySource]; copySource++; dstPlace++; } } // Use next bit from "code" byte currCodeByte <<= 1; validBitCount -= 1; } return(dst); }