private static SinFile.BlockInfoHeader GetBIH(BinaryReader br) { SinFile.BlockInfoHeader bih = new SinFile.BlockInfoHeader(); bih.magic = br.ReadBytes(4); bih.BIHLength = Utility.ReadIntBigEndian(br); if (SinFile.isCompressed(bih) && bih.BIHLength != _BIHSizeCompressed) { throw new FormatException("woot, compressed bih is spooky"); } bih.dataStart = Utility.ReadLongBigEndian(br); if (SinFile.isCompressed(bih)) { bih.blockSize = Utility.ReadLongBigEndian(br); } bih.dataLength = Utility.ReadLongBigEndian(br); bih.dataDest = Utility.ReadLongBigEndian(br); if (SinFile.isCompressed(bih)) { bih.destLength = Utility.ReadLongBigEndian(br); } //skip for performance br.BaseStream.Position += 0x24; //bih.HashType = Utility.ReadIntBigEndian(br); //bih.SHA256 = br.ReadBytes(0x20); return(bih); }
private static void ExtractSinData(BackgroundWorker sender, BinaryReader br, List <SinFile.BlockInfoHeader> bihs, string destination, bool showProgress = true) { using (FileStream fsw = new FileStream(destination, FileMode.Create)) using (BinaryWriter bw = new BinaryWriter(fsw)) { int SinVersion = SinFile.GetSinVersion(br); long previousDest = 0, previousLength = 0; int dataStart = SinFile.GetDataStart(br); br.BaseStream.Position = dataStart; for (int i = 0; i < bihs.Count; i++) { SinFile.BlockInfoHeader bih = bihs[i]; if (previousDest + previousLength < bih.dataDest) { FillFF(fsw, (previousDest + previousLength), (bih.dataDest - previousDest - previousLength)); } if (SinVersion != 2) { br.BaseStream.Position = dataStart + bih.dataStart; } fsw.Position = bih.dataDest; if (SinFile.isCompressed(bih)) { DecompressAndCopy(br, bw, bih); } else { CopyBytes(br, bw, bih.dataLength); } previousDest = bih.dataDest; previousLength = SinFile.isCompressed(bih) ? bih.destLength : bih.dataLength; if (showProgress) { sender.ReportProgress((int)((float)i / bihs.Count * 100)); } } long finallength = SinFile.GetFinalLength(fsw); if (finallength > previousDest + previousLength) { FillFF(fsw, (previousDest + previousLength), (finallength - previousDest - previousLength)); } if (showProgress) { sender.ReportProgress(100); } } }
private static void DecompressAndCopy(BinaryReader _in, BinaryWriter _out, SinFile.BlockInfoHeader bih) { if (bih.blockSize != bih.destLength) { throw new Exception("This decompression was unexpected"); } byte[] compressed = new byte[bih.dataLength]; _in.Read(compressed, 0, compressed.Length); byte[] decompressed = LZ4.LZ4Codec.Decode(compressed, 0, compressed.Length, Convert.ToInt32(bih.blockSize)); _out.Write(decompressed, 0, decompressed.Length); }
//roughly taken from flashtool public static List<SinFile.BlockInfoHeader> GetBIHs(BinaryReader br) { br.BaseStream.Position = 11; int BIHLength = Utility.ReadIntBigEndian(br); if (BIHLength % _BIHSize != 0) throw new Exception("Woot m8, v2 too spooky"); List<SinFile.BlockInfoHeader> bihs = new List<SinFile.BlockInfoHeader>(); for (int i = 0; i < (BIHLength / _BIHSize); i++) { SinFile.BlockInfoHeader bih = new SinFile.BlockInfoHeader(); bih.dataDest = Utility.ReadIntBigEndian(br); bih.dataLength = Utility.ReadIntBigEndian(br); bihs.Add(bih); br.BaseStream.Position += 0x21; //SHA256 and 1 unknown byte } return bihs; }
//roughly taken from flashtool public static List <SinFile.BlockInfoHeader> GetBIHs(BinaryReader br) { br.BaseStream.Position = 11; int BIHLength = Utility.ReadIntBigEndian(br); if (BIHLength % _BIHSize != 0) { throw new Exception("Woot m8, v2 too spooky"); } List <SinFile.BlockInfoHeader> bihs = new List <SinFile.BlockInfoHeader>(); for (int i = 0; i < (BIHLength / _BIHSize); i++) { SinFile.BlockInfoHeader bih = new SinFile.BlockInfoHeader(); bih.dataDest = Utility.ReadIntBigEndian(br); bih.dataLength = Utility.ReadIntBigEndian(br); bihs.Add(bih); br.BaseStream.Position += 0x21; //SHA256 and 1 unknown byte } return(bihs); }
private static SinFile.BlockInfoHeader GetBIH(BinaryReader br) { SinFile.BlockInfoHeader bih = new SinFile.BlockInfoHeader(); bih.magic = br.ReadBytes(4); bih.BIHLength = Utility.ReadIntBigEndian(br); if (SinFile.isCompressed(bih) && bih.BIHLength != _BIHSizeCompressed) throw new FormatException("woot, compressed bih is spooky"); bih.dataStart = Utility.ReadLongBigEndian(br); if (SinFile.isCompressed(bih)) bih.blockSize = Utility.ReadLongBigEndian(br); bih.dataLength = Utility.ReadLongBigEndian(br); bih.dataDest = Utility.ReadLongBigEndian(br); if (SinFile.isCompressed(bih)) bih.destLength = Utility.ReadLongBigEndian(br); //skip for performance br.BaseStream.Position += 0x24; //bih.HashType = Utility.ReadIntBigEndian(br); //bih.SHA256 = br.ReadBytes(0x20); return bih; }