/// <summary>从数据流中读取消息头</summary> /// <param name="stream"></param> public void Read(Stream stream) { var reader = new BinaryReaderX(stream); reader.Settings.EncodeInt = true; Flag = (Flags)reader.ReadByte(); if (HasFlag(Flags.Channel)) Channel = reader.ReadByte(); if (HasFlag(Flags.SessionID)) SessionID = reader.ReadInt32(); if (HasFlag(Flags.Length)) Length = reader.ReadInt32(); }
public G1T(Stream input, Platform platform) { _platform = platform; using (BinaryReaderX br = new BinaryReaderX(input)) { //Deciding on Endianess var magic1 = br.ReadString(4); br.ByteOrder = ByteOrder = (magic1 == "GT1G") ? ByteOrder.LittleEndian : ByteOrder.BigEndian; br.BaseStream.Position = 0; //Header header = br.ReadStruct <Header>(); //OffsetList br.BaseStream.Position = header.dataOffset; var offsetList = br.ReadMultiple <int>(header.texCount); //Meta meta = new List <Meta>(); for (int i = 0; i < header.texCount; i++) { br.BaseStream.Position = header.dataOffset + offsetList[i]; var metainfo = br.ReadStruct <Meta>(); meta.Add(metainfo); byte[] ext = null; if (metainfo.extHeader > 0) { var extSize = br.ReadInt32(); ext = br.ReadBytes(extSize - 4); } metaExt.Add(ext); //Check if format exists switch (_platform) { case Platform.N3DS: if (!Support.N3DSFormat.ContainsKey(metainfo.format)) { throw new Exception($"Unsupported image format 0x{metainfo.format:X2}."); } break; case Platform.PS: if (!Support.PSFormat.ContainsKey(metainfo.format)) { throw new Exception($"Unsupported image format 0x{metainfo.format:X2}."); } break; case Platform.Vita: if (!Support.VitaFormat.ContainsKey(metainfo.format)) { throw new Exception($"Unsupported image format 0x{metainfo.format:X2}."); } break; } var format = (_platform == Platform.Vita) ? Support.VitaFormat[meta[i].format] : (_platform == Platform.N3DS) ? Support.N3DSFormat[meta[i].format] : Support.PSFormat[meta[i].format]; IImageSwizzle swizzle = null; if (_platform == Platform.Vita) { swizzle = new VitaSwizzle(metainfo.width, metainfo.height, format.FormatName.Contains("DXT")); } else if (_platform == Platform.N3DS) { swizzle = new CTRSwizzle(metainfo.width, metainfo.height, 2); } else if (format.FormatName.Contains("DXT")) { swizzle = new BlockSwizzle(metainfo.width, metainfo.height); } var setting = new ImageSettings { Width = metainfo.width, Height = metainfo.height, Swizzle = swizzle, Format = format }; settings.Add(setting); var length = metainfo.width * metainfo.height * format.BitDepth / 8; bmps.Add(Common.Load(br.ReadBytes(length), setting)); } } }
public BTXT(string filename) { using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReaderX br = new BinaryReaderX(fs); // Header Header.Identifier = br.ReadBytes(8); if (!Header.Identifier.SequenceEqual(new byte[] { 0x0, 0x0, 0x0, 0x0, 0x24, 0x10, 0x12, 0xFF })) { throw new InvalidBTXTException("The file provided is not a valid BTXT file."); } Header.NumberOfLabels = br.ReadUInt16(); Header.NumberOfStrings = br.ReadUInt16(); // Create labels for (int i = 0; i < Header.NumberOfLabels; i++) { Labels.Add(new Label()); } // Attributes for (int i = 0; i < Header.NumberOfLabels; i++) { Label label = Labels[i]; label.StringCount = br.ReadUInt32(); for (int j = 0; j < label.StringCount; j++) { String str = new String(); str.ID = br.ReadUInt32(); label.Strings.Add(str); } } // Offsets for (int i = 0; i < Header.NumberOfLabels + Header.NumberOfStrings; i++) { Offsets.Add(br.ReadUInt32()); } // Set the offset start position uint offsetStart = (uint)br.BaseStream.Position; Offsets.Add((uint)br.BaseStream.Length - offsetStart); // Add an extra offset at the end // Labels for (int i = 0; i < Header.NumberOfLabels; i++) { Label label = Labels[i]; label.Name = Encoding.ASCII.GetString(br.ReadBytes((int)(Offsets[i + 1] - Offsets[i]))).TrimEnd('\0'); } // Text int index = 0; for (int i = 0; i < Header.NumberOfLabels; i++) { Label label = Labels[i]; for (int j = 0; j < label.StringCount; j++) { String str = label.Strings[j]; str.Text = FileEncoding.GetString(br.ReadBytes((int)(Offsets[Header.NumberOfLabels + index + 1] - Offsets[Header.NumberOfLabels + index]))).TrimEnd('\0'); index++; } } br.Close(); } }
public static byte[] Decompress(Stream instream, ByteOrder byteOrder) { using (var br = new BinaryReaderX(instream, true, byteOrder)) { var offset = 0; List <byte> output = new List <byte>(); #region 16-byte Header if (br.ReadString(4) != "MIO0") { throw new Exception("Not a valid MIO0 compressed file!"); } int decompressedLength = br.ReadInt32(); int compressedOffset = br.ReadInt32() + offset; int uncompressedOffset = br.ReadInt32() + offset; #endregion int currentOffset; while (output.Count < decompressedLength) { byte bits = br.ReadByte(); //byte of layout bits BitArray arrayOfBits = new BitArray(new byte[1] { bits }); for (int i = 7; i > -1 && (output.Count < decompressedLength); i--) //iterate through layout bits { if (arrayOfBits[i] == true) { //non-compressed //add one byte from uncompressedOffset to newFile currentOffset = (int)br.BaseStream.Position; br.BaseStream.Seek(uncompressedOffset, SeekOrigin.Begin); output.Add(br.ReadByte()); uncompressedOffset++; br.BaseStream.Seek(currentOffset, SeekOrigin.Begin); } else { //compressed //read 2 bytes //4 bits = length //12 bits = offset currentOffset = (int)br.BaseStream.Position; br.BaseStream.Seek(compressedOffset, SeekOrigin.Begin); byte byte1 = br.ReadByte(); byte byte2 = br.ReadByte(); compressedOffset += 2; //Note: For Debugging, binary representations can be printed with: Convert.ToString(numberVariable, 2); byte byte1Upper = (byte)((byte1 & 0x0F)); //offset bits byte byte1Lower = (byte)((byte1 & 0xF0) >> 4); //length bits int combinedOffset = ((byte1Upper << 8) | byte2); int finalOffset = 1 + combinedOffset; int finalLength = 3 + byte1Lower; for (int k = 0; k < finalLength; k++) //add data for finalLength iterations { output.Add(output[output.Count - finalOffset]); //add byte at offset (fileSize - finalOffset) to file } br.BaseStream.Seek(currentOffset, SeekOrigin.Begin); //return to layout bits } } } return(output.ToArray()); } }
public BCFNT(Stream input) { using (var br = new BinaryReaderX(input)) { // @todo: read as sections br.ReadStruct <CFNT>(); if (br.ReadString(4) == "GLGR") { _usesGlgr = true; var glgrSize = br.ReadInt32(); br.BaseStream.Position -= 8; _glgr = br.ReadBytes(glgrSize); } else { br.BaseStream.Position -= 4; } finf = br.ReadStruct <FINF>(); // read TGLP br.BaseStream.Position = finf.tglp_offset - 8; tglp = br.ReadStruct <TGLP>(); // read image data br.BaseStream.Position = tglp.sheet_data_offset; int width = tglp.sheet_width; int height = tglp.sheet_height; if (_usesGlgr) { bmps = new Bitmap[tglp.num_sheets]; for (int i = 0; i < tglp.num_sheets; i++) { var compSize = br.ReadInt32(); var decomp = Huffman.Decompress(new MemoryStream(br.ReadBytes(compSize)), 8); bmps[i] = Image.Common.Load(decomp, new ImageSettings { Width = width, Height = height, Format = ImageSettings.ConvertFormat(tglp.sheet_image_format & 0x7fff) }); } } else { bmps = Enumerable.Range(0, tglp.num_sheets).Select(_ => Image.Common.Load(br.ReadBytes(tglp.sheet_size), new ImageSettings { Width = width, Height = height, Format = ImageSettings.ConvertFormat(tglp.sheet_image_format) })).ToArray(); } // read CWDH for (int offset = finf.cwdh_offset; offset != 0;) { br.BaseStream.Position = offset - 8; var cwdh = br.ReadStruct <CWDH>(); for (int i = cwdh.start_index; i <= cwdh.end_index; i++) { lstCWDH.Add(br.ReadStruct <CharWidthInfo>()); } offset = cwdh.next_offset; } // read CMAP for (int offset = finf.cmap_offset; offset != 0;) { br.BaseStream.Position = offset - 8; var cmap = br.ReadStruct <CMAP>(); switch (cmap.mapping_method) { case 0: var charOffset = br.ReadUInt16(); for (char i = cmap.code_begin; i <= cmap.code_end; i++) { int idx = i - cmap.code_begin + charOffset; dicCMAP[i] = idx < ushort.MaxValue ? idx : 0; } break; case 1: for (char i = cmap.code_begin; i <= cmap.code_end; i++) { int idx = br.ReadInt16(); if (idx != -1) { dicCMAP[i] = idx; } } break; case 2: var n = br.ReadUInt16(); for (int i = 0; i < n; i++) { char c = br.ReadChar(); int idx = br.ReadInt16(); if (idx != -1) { dicCMAP[c] = idx; } } break; default: throw new Exception("Unsupported mapping method"); } offset = cmap.next_offset; } } }
public void extractCfgBin(BinaryReaderX br, string prefix = "") { long bk; //Header Header cfgHeader = br.ReadStruct <Header>(); headerList.Add(cfgHeader); List <EditorStruct> editorEntriesLocal = new List <EditorStruct>(); editorEntriesLocal.Add(br.ReadStruct <EditorStruct>()); //getting Editor's notes entries while (true) { Label label = new Label(); EditorStruct entryE = br.ReadStruct <EditorStruct>(); editorEntriesLocal.Add(entryE); label.Name = prefix + "editor" + (editorEntriesLocal.Count - 1).ToString(); label.TextID = entryE.ID; label.TextOffset = cfgHeader.dataOffset + entryE.entryOffset; bk = br.BaseStream.Position; br.BaseStream.Position = label.TextOffset; string text = ""; byte part = br.ReadByte(); while (part != 0) { text += Encoding.GetEncoding("ascii").GetString(new byte[] { part }); part = br.ReadByte(); } br.BaseStream.Position = label.TextOffset; label.Text = text; br.BaseStream.Position = bk; Labels.Add(label); if (entryE.endingFlag == 0x0101) { break; } } editorEntries.Add(editorEntriesLocal); bool found = false; bk = br.BaseStream.Position; while (br.BaseStream.Position < cfgHeader.dataOffset && found == false) { if (br.ReadInt32() == (int)(editorEntries[editorEntries.Count - 1][editorEntries[editorEntries.Count - 1].Count - 1].entryOffset + Labels[Labels.Count - 1].Text.Length + 1)) { found = true; } } br.BaseStream.Position = bk; if (found == false) { editorRest.Add(br.ReadBytes((int)(cfgHeader.dataOffset - br.BaseStream.Position))); textRest.Add(null); textEntries.Add(null); } else { editorRest.Add(null); List <TextStruct> textEntriesLocal = new List <TextStruct>(); textEntriesLocal.Add(br.ReadStruct <TextStruct>()); //getting text entries TextStruct entryT; TextStruct entryT2; int entryCount = 1; do { Label label = new Label(); entryT = br.ReadStruct <TextStruct>(); textEntriesLocal.Add(entryT); entryT2 = br.ReadStruct <TextStruct>(); br.BaseStream.Position -= 0x14; if (entryT.entryOffset != 0xFFFFFFFF) { label.Name = prefix + "text" + entryCount.ToString(); entryCount++; label.TextID = entryT.ID; label.TextOffset = cfgHeader.dataOffset + entryT.entryOffset; bk = br.BaseStream.Position; br.BaseStream.Position = label.TextOffset; int count = 0; byte part = br.ReadByte(); while (part != 0) { count++; part = br.ReadByte(); } count++; br.BaseStream.Position = label.TextOffset; label.Text = getUnicodeString(new BinaryReaderX(new MemoryStream(br.ReadBytes(count)))); br.BaseStream.Position = bk; Labels.Add(label); } } while (entryT.unk3 != 0xffffff00 && (entryT2.entryOffset <= br.BaseStream.Length || entryT2.entryOffset == 0xFFFFFFFF)); textEntries.Add(textEntriesLocal); if (br.BaseStream.Position < cfgHeader.dataOffset) { textRest.Add(br.ReadBytes((int)cfgHeader.dataOffset - (int)br.BaseStream.Position)); } } }
public BXLIM(Stream input) { using (var br = new BinaryReaderX(input)) { var tex = br.ReadBytes((int)br.BaseStream.Length - 40); sections = br.ReadSections(); byteOrder = br.ByteOrder; switch (sections.Header.magic) { case "CLIM": BCLIMHeader = sections[0].Data.BytesToStruct <BCLIMImageHeader>(byteOrder); Settings = new Kontract.Image.ImageSettings { Width = BCLIMHeader.width, Height = BCLIMHeader.height, Format = DSFormat[BCLIMHeader.format], Swizzle = new CTRSwizzle(BCLIMHeader.width, BCLIMHeader.height, BCLIMHeader.swizzleTileMode) }; Image = Kontract.Image.Common.Load(tex, Settings); break; case "FLIM": if (byteOrder == ByteOrder.LittleEndian) { BFLIMHeader = sections[0].Data.BytesToStruct <BFLIMImageHeader>(byteOrder); Settings = new Kontract.Image.ImageSettings { Width = BFLIMHeader.width, Height = BFLIMHeader.height, Format = DSFormat[BFLIMHeader.format], Swizzle = new CTRSwizzle(BFLIMHeader.width, BFLIMHeader.height, BFLIMHeader.swizzleTileMode) }; Image = Kontract.Image.Common.Load(tex, Settings); } else { BFLIMHeader = sections[0].Data.BytesToStruct <BFLIMImageHeader>(byteOrder); var format = WiiUFormat[BFLIMHeader.format]; var isBlockBased = new[] { 10, 11, 12, 13, 14, 15, 16, 17, 21, 22, 23 }.Contains(BFLIMHeader.format); // hax Settings = new Kontract.Image.ImageSettings { Width = BFLIMHeader.width, Height = BFLIMHeader.height, Format = format, Swizzle = new WiiUSwizzle(BFLIMHeader.swizzleTileMode, isBlockBased, format.BitDepth, BFLIMHeader.width, BFLIMHeader.height) }; // Uncomment the following line to use the padded width/height instead //(Settings.Width, Settings.Height) = (Settings.Swizzle.Width, Settings.Swizzle.Height); Image = Kontract.Image.Common.Load(tex, Settings); } break; default: throw new NotSupportedException($"Unknown image format {sections.Header.magic}"); } } }
public static byte[] Compress(Stream input, ByteOrder byteOrder) { using (var br = new BinaryReaderX(input, true)) { var cap = 0x111; var sz = input.Length; var cmds = new List <byte>(); var ctrl = new List <byte>(); var raws = new List <byte>(); var cmdpos = 0; cmds.Add(0); var pos = 0; byte flag = 0x80; while (pos < sz) { var hitp = 0; var hitl = 0; _search(input, pos, sz, cap, ref hitp, ref hitl); if (hitl < 3) { raws.Add(br.ScanBytes(pos)[0]); cmds[cmdpos] |= flag; pos += 1; } else { var tstp = 0; var tstl = 0; _search(input, pos + 1, sz, cap, ref tstp, ref tstl); if ((hitl + 1) < tstl) { raws.Add(br.ScanBytes(pos)[0]); cmds[cmdpos] |= flag; pos += 1; flag >>= 1; if (flag == 0) { flag = 0x80; cmdpos = cmds.Count(); cmds.Add(0); } hitl = tstl; hitp = tstp; } var e = pos - hitp - 1; pos += hitl; if (hitl < 0x12) { hitl -= 2; ctrl.AddRange(BitConverter.GetBytes((ushort)((hitl << 12) | e)).Reverse()); } else { ctrl.AddRange(BitConverter.GetBytes((ushort)(e)).Reverse()); raws.Add((byte)(hitl - 0x12)); } } flag >>= 1; if (flag == 0) { flag = 0x80; cmdpos = cmds.Count(); cmds.Add(0); } } if (flag == 0x80) { cmds.RemoveAt(cmdpos); } var v = 4 - (cmds.Count() & 3); cmds.AddRange(new byte[v & 3]); var l = cmds.Count() + 16; var o = ctrl.Count() + l; List <byte> header = new List <byte>(); header.AddRange(Encoding.ASCII.GetBytes("Yay0")); header.AddRange((byteOrder == ByteOrder.LittleEndian) ? BitConverter.GetBytes((int)sz) : BitConverter.GetBytes((int)sz).Reverse()); header.AddRange((byteOrder == ByteOrder.LittleEndian) ? BitConverter.GetBytes(l) : BitConverter.GetBytes(l).Reverse()); header.AddRange((byteOrder == ByteOrder.LittleEndian) ? BitConverter.GetBytes(o) : BitConverter.GetBytes(o).Reverse()); header.AddRange(cmds); header.AddRange(ctrl); header.AddRange(raws); return(header.ToArray()); } }
private void btnLookup_Click(object sender, EventArgs e) { Encoding enc = Encoding.Unicode; FileInfo file = new FileInfo(txtFile.Text.Trim()); if (file.Exists) { using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReaderX br = new BinaryReaderX(fs, ByteOrder.LittleEndian); txtResults.Text = string.Empty; uint offset = Convert.ToUInt32(txtOffset.Text.Trim(), 16); uint leneance = Convert.ToUInt32(txtLeneance.Text.Trim()); uint value = 0; List <uint> pointers = new List <uint>(); while (br.BaseStream.Position < br.BaseStream.Length - 4) { bool found = false; uint pointer = (uint)br.BaseStream.Position; value = br.ReadUInt32(); if (value < br.BaseStream.Length - 4) { uint shift = 0; uint.TryParse(Settings.Default.DirectorShift, out shift); if (value == (offset + shift)) { found = true; } else if (value >= (offset + shift - leneance) && value < offset + shift) { found = true; } else if (value <= (offset + shift + leneance) && value > offset + shift) { found = true; } if (found) { pointers.Add(pointer); } } } if (pointers.Count > 0) { List <byte> result = new List <byte>(); br.BaseStream.Seek(offset, SeekOrigin.Begin); while (br.BaseStream.Position < br.BaseStream.Length) { byte[] unichar = br.ReadBytes(2); if (unichar[0] != 0x0 || unichar[1] != 0x0) { result.AddRange(unichar); } else { break; } } string strResult = enc.GetString(result.ToArray()); txtResults.AppendText("<entry encoding=\"" + enc.EncodingName + "\" name=\"\" offset=\"" + offset.ToString("X2") + "\" relocatable=\"true\" max_length=\"0\">"); txtResults.AppendText("\r\n"); foreach (uint p in pointers) { txtResults.AppendText("\t<pointer address=\"" + p.ToString("X2") + "\" />"); txtResults.AppendText("\r\n"); } txtResults.AppendText("\t<original>" + strResult + "</original>"); txtResults.AppendText("\r\n"); txtResults.AppendText("\t<edited>" + strResult + "</edited>"); txtResults.AppendText("\r\n"); txtResults.AppendText("</entry>"); } else { txtResults.Text = "No pointers found..."; } br.Close(); } } }
// Dumper private void workerDumper_DoWork(object sender, DoWorkEventArgs e) { FileStream fs = new FileStream(txtFilename.Text, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReaderX br = new BinaryReaderX(fs, ByteOrder.LittleEndian); // Pointer Tables _pointers = new Dictionary <long, long>(); _workerDumper.ReportProgress(0, "STATUS|Dumping pointers..."); foreach (Bound pointerBound in _kup.PointerTables) { long end = Math.Max(4, pointerBound.EndLong); if (end == 4) { end += pointerBound.StartLong; } br.BaseStream.Seek(pointerBound.StartLong, SeekOrigin.Begin); while (br.BaseStream.Position < end) { uint offset = br.ReadUInt32() - _kup.RamOffsetUInt; if (offset < br.BaseStream.Length) { _pointers.Add(br.BaseStream.Position - sizeof(uint), offset); // AAAHAAAAARRRRRRGGRGGGGHHHHHHH } _workerDumper.ReportProgress((int)(((double)br.BaseStream.Position - pointerBound.StartLong) / ((double)pointerBound.EndLong - pointerBound.StartLong) * prgBottom.Maximum), "BOTTOM"); } } _workerDumper.ReportProgress(0, "STATUS|Found " + _pointers.Count + " pointers..."); _workerDumper.ReportProgress(0, "STATUS|Dumping strings..."); for (int i = 0; i < _kup.StringBounds.Count; i++) { Bound stringBound = _kup.StringBounds[i]; _workerDumper.ReportProgress((int)(((double)i + 1 / (double)_kup.StringBounds.Count) * prgBottom.Maximum), "BOTTOM"); if (stringBound.Dumpable) { var result = new List <byte>(); var offset = stringBound.StartLong; long jumpBack = 0; br.BaseStream.Seek(stringBound.StartLong, SeekOrigin.Begin); while (br.BaseStream.Position < stringBound.EndLong) { var unichar = br.ReadBytes(_kup.Encoding.IsSingleByte ? 1 : 2); result.AddRange(unichar); if (stringBound.Injectable) { if (jumpBack == 0 && (_pointers.Values.Contains(br.BaseStream.Position) || br.BaseStream.Position == stringBound.EndLong)) { jumpBack = br.BaseStream.Position; } if ((_pointers.Values.Contains(br.BaseStream.Position) || br.BaseStream.Position == stringBound.EndLong) && (result[result.Count - 1] == 0x00 && (_kup.Encoding.IsSingleByte || result[result.Count - 2] == 0x00))) { if (result[result.Count - 1] == 0x00 && (_kup.Encoding.IsSingleByte || result[result.Count - 2] == 0x00)) { result.RemoveAt(result.Count - 1); if (!_kup.Encoding.IsSingleByte) { result.RemoveAt(result.Count - 1); } } var entry = new Entry { OffsetLong = offset }; // Merging var matched = false; foreach (var ent in _kup.Entries) { if (ent.Offset == entry.Offset) { entry = ent; matched = true; break; } } // Pointers foreach (var key in _pointers.Keys) { if (_pointers[key] == offset) { entry.AddPointer(key); } } // Text if (Equals(_kup.Encoding, Encoding.ASCII)) { var parsed = new StringBuilder(); foreach (var b in result) { parsed.Append((char)b); } entry.OriginalText = _gameHandler.GetKuriimuString(parsed.ToString()).Replace("\0", "<null>").Replace("\n", "\r\n");; } else { entry.OriginalText = _gameHandler.GetKuriimuString(_kup.Encoding.GetString(result.ToArray())).Replace("\0", "<null>").Replace("\n", "\r\n"); } // Not Matched if (!matched) { entry.Relocatable = stringBound.Injectable; entry.Name = Regex.Match(entry.OriginalText, @"\w+", RegexOptions.IgnoreCase).Value; entry.EditedText = entry.OriginalText; _kup.Entries.Add(entry); } if (entry.OriginalText.Contains("<null>")) { _workerDumper.ReportProgress(0, "STATUS|Found a potentially broken string at " + entry.Offset + ": " + entry.Name + "|" + entry.Offset); } if (jumpBack > 0) { br.BaseStream.Seek(jumpBack, SeekOrigin.Begin); jumpBack = 0; } offset = br.BaseStream.Position; result.Clear(); } } else { if (br.BaseStream.Position == stringBound.EndLong) { if (result.Count >= (_kup.Encoding.IsSingleByte ? 1 : 2)) { if (result[result.Count - 1] == 0x00 && (_kup.Encoding.IsSingleByte || result[result.Count - 2] == 0x00)) { result.RemoveAt(result.Count - 1); if (!_kup.Encoding.IsSingleByte) { result.RemoveAt(result.Count - 1); } } var entry = new Entry { OffsetLong = stringBound.StartLong }; // Merging var matched = false; foreach (var ent in _kup.Entries) { if (ent.Offset == entry.Offset) { entry = ent; matched = true; break; } } // Text if (Equals(_kup.Encoding, Encoding.ASCII)) { var parsed = new StringBuilder(); foreach (var b in result) { parsed.Append((char)b); } entry.OriginalText = _gameHandler.GetKuriimuString(parsed.ToString()).Replace("\0", "<null>").Replace("\n", "\r\n");; } else { entry.OriginalText = _gameHandler.GetKuriimuString(_kup.Encoding.GetString(result.ToArray())).Replace("\0", "<null>").Replace("\n", "\r\n"); } // Not Matched if (!matched) { entry.Relocatable = stringBound.Injectable; entry.Name = Regex.Match(entry.OriginalText, @"\w+", RegexOptions.IgnoreCase).Value; entry.EditedText = entry.OriginalText; entry.MaxLength = entry.EditedText.Length; _kup.Entries.Add(entry); } } result.Clear(); } } _workerDumper.ReportProgress((int)(((double)br.BaseStream.Position - stringBound.StartLong) / ((double)stringBound.EndLong - stringBound.StartLong) * prgTop.Maximum), "TOP"); } } } _workerDumper.ReportProgress(0, "STATUS|Dumped " + _kup.Entries.Count + " strings..."); br.Close(); }
public XF(Stream input) { using (var br = new BinaryReaderX(input)) { //load files xpck = new XPCK(input); //get xi image to bmp xi = new IMGC(xpck.Files[0].FileData); bmp = xi.Image; //decompress fnt.bin var tempCharSizeInfo = new List <CharSizeInfo>(); var largeChars = new List <CharacterMap>(); var smallChars = new List <CharacterMap>(); using (var fntR = new BinaryReaderX(xpck.Files[1].FileData, true)) { Header = fntR.ReadType <XFHeader>(); fntR.BaseStream.Position = Header.table0Offset << 2; t0Comp = (Level5.Method)(fntR.ReadInt32() & 0x7); fntR.BaseStream.Position -= 4; tempCharSizeInfo = new BinaryReaderX(new MemoryStream(Level5.Decompress(fntR.BaseStream))).ReadMultiple <CharSizeInfo>(Header.table0EntryCount); fntR.BaseStream.Position = Header.table1Offset << 2; t1Comp = (Level5.Method)(fntR.ReadInt32() & 0x7); fntR.BaseStream.Position -= 4; largeChars = new BinaryReaderX(new MemoryStream(Level5.Decompress(fntR.BaseStream))).ReadMultiple <CharacterMap>(Header.table1EntryCount); fntR.BaseStream.Position = Header.table2Offset << 2; t2Comp = (Level5.Method)(fntR.ReadInt32() & 0x7); fntR.BaseStream.Position -= 4; smallChars = new BinaryReaderX(new MemoryStream(Level5.Decompress(fntR.BaseStream))).ReadMultiple <CharacterMap>(Header.table2EntryCount); } Textures = new List <Bitmap>(); var bmpInfo = new BitmapInfo(bmp); Textures.Add(bmpInfo.CreateChannelBitmap(BitmapInfo.Channel.Red)); Textures.Add(bmpInfo.CreateChannelBitmap(BitmapInfo.Channel.Green)); Textures.Add(bmpInfo.CreateChannelBitmap(BitmapInfo.Channel.Blue)); //Add Characters Characters = new List <XFCharacter>(); foreach (var glyph in largeChars) { var newChar = new XFCharacter { Character = glyph.code_point, TextureID = (int)glyph.ColorChannel, GlyphX = (int)glyph.ImageOffsetX, GlyphY = (int)glyph.ImageOffsetY, GlyphWidth = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].glyph_width, GlyphHeight = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].glyph_height, CharacterWidth = (int)glyph.CharWidth, OffsetX = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].offset_x, OffsetY = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].offset_y, }; Characters.Add(newChar); } /*foreach (var glyph in smallChars) * Characters.Add(new XFCharacter * { * Character = glyph.code_point, * TextureID = (int)glyph.ColorChannel, * GlyphX = (int)glyph.ImageOffsetX, * GlyphY = (int)glyph.ImageOffsetY, * GlyphWidth = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].glyph_width, * GlyphHeight = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].glyph_height, * CharacterWidth = (int)glyph.CharWidth, * OffsetX = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].offset_x, * OffsetY = tempCharSizeInfo[(int)glyph.CharSizeInfoIndex].offset_y, * });*/ //Add Textures } }
public GFDv2(FileStream input) { _sourceFile = input.Name; if (_texAdapters == null || _texAdapters.Count == 0) { _texAdapters = PluginLoader.Instance.GetAdapters <IMtFrameworkTextureAdapter>(); } using (var br = new BinaryReaderX(input)) { // Set endianess if (br.PeekString(4, Encoding.ASCII) == "\0DFG") { br.ByteOrder = ByteOrder = ByteOrder.BigEndian; br.BitOrder = BitOrder = BitOrder.LSBFirst; } // Header Header = br.ReadType <FileHeader>(); HeaderF = br.ReadMultiple <float>(Header.FCount); // Name br.ReadInt32(); Name = br.ReadCStringASCII(); // Characters Characters = br.ReadMultiple <CharacterInfo>(Header.CharacterCount).Select(ci => new GFDv2Character { Character = ci.Character, TextureID = (int)ci.Block1.TextureIndex, GlyphX = (int)ci.Block1.GlyphX, GlyphY = (int)ci.Block1.GlyphY, Block2Trailer = (int)ci.Block2.Block2Trailer, GlyphWidth = (int)ci.Block2.GlyphWidth, GlyphHeight = (int)ci.Block2.GlyphHeight, CharacterWidth = (int)ci.Block3.CharacterWidth, CharacterHeight = (int)ci.Block3.CharacterHeight, XAdjust = ci.XAdjust, YAdjust = ci.YAdjust }).ToList(); // Textures Textures = new List <Bitmap>(); for (var i = 0; i < Header.FontTexCount; i++) { IMtFrameworkTextureAdapter texAdapter = _texAdapters.Where(adapter => adapter is IIdentifyFiles). FirstOrDefault(adapter => ((IIdentifyFiles)adapter). Identify(new StreamInfo(File.OpenRead(GetTexName(_sourceFile, i)), GetTexName(_sourceFile, i)), null)); if (texAdapter == null) { continue; } ((ILoadFiles)texAdapter).Load(new StreamInfo(File.OpenRead(GetTexName(_sourceFile, i)), GetTexName(_sourceFile, i)), null); Textures.Add(((IImageAdapter)texAdapter).BitmapInfos[0].Image); } } }
public BCH(string filename) { using (BinaryReaderX br = new BinaryReaderX(File.OpenRead(filename))) { _file = br.ReadAllBytes(); //Header header = new Header(br.BaseStream); if (header.dataSize != 0) { //get entryCount br.BaseStream.Position = header.gpuCommandsOffset; int entryCount = 0; List <uint> wordCount = new List <uint>(); wordCount.Add(0); using (var br2 = new BinaryReaderX(new MemoryStream(br.ReadBytes((int)header.gpuCommandsSize)))) { while (br2.BaseStream.Position < br2.BaseStream.Length - 2) { br2.BaseStream.Position += 4; var comp = br2.ReadUInt16(); wordCount[wordCount.Count - 1] += 2; if (comp == 0x23d) { entryCount++; wordCount.Add(0); } br2.BaseStream.Position += 2; } } //get commands br.BaseStream.Position = header.gpuCommandsOffset; for (int i = 0; i < entryCount; i++) { picaEntries.Add(new PICACommandReader(br.BaseStream, wordCount[i])); } //loop through commandReaders to get textures for (int i = 0; i < entryCount; i++) { var size = picaEntries[i].getTexUnit0Size(); if (size.Height != 0 && size.Width != 0) { br.BaseStream.Position = header.dataOffset + picaEntries[i].getTexUnit0Address(); var format = (byte)picaEntries[i].getTexUnit0Format(); int bitDepth = Support.CTRFormat[format].BitDepth; //for (int j = 0; j <= picaEntries[i].getTexUnit0LoD(); j++) //{ origValues.Add(new TexEntry(size.Width, size.Height, format)); var settings = new ImageSettings { Width = size.Width, Height = size.Height, Format = Support.CTRFormat[format], Swizzle = new CTRSwizzle(size.Width, size.Height) }; _settings.Add(settings); // bmps.Add(Common.Load(br.ReadBytes((((size.Width >> j) * (size.Height >> j)) * bitDepth) / 8), settings)); //} bmps.Add(Common.Load(br.ReadBytes((((size.Width) * (size.Height)) * bitDepth) / 8), settings)); br.BaseStream.Position = (br.BaseStream.Position + 0x7f) & ~0x7f; } } } } }
public static void Decrypt(object sender, EventArgs e) { var tsi = sender as ToolStripMenuItem; var name = (tsi.Tag.ToString() == "normal") ? "3DS" : tsi.Tag.ToString(); FileStream openFile; FileStream saveFile = null; if ((Types)tsi.Tag != Types.NSW_XCI && (Types)tsi.Tag != Types.NSW_NCA) { if (!Shared.PrepareFiles("Open an encrypted " + name + " file...", "Save your decrypted file...", ".dec", out openFile, out saveFile)) { return; } } else { var ofd = new OpenFileDialog { Title = "Open an encrypted " + name + " file...", Filter = "All Files (*.*)|*.*" }; if (ofd.ShowDialog() == DialogResult.OK) { openFile = File.Open(ofd.FileName, FileMode.Open, FileAccess.ReadWrite); } else { return; } } bool show = true; try { using (var openBr = new BinaryReaderX(openFile)) { switch (tsi.Tag) { case Types.BlowFishCBC: using (var outFs = new BinaryWriterX(saveFile)) { var key = InputBox.Show("Input decryption key:", "Decrypt Blowfish"); if (key == String.Empty) { throw new Exception("Key can't be empty!"); } var bf = new BlowFish(key); outFs.Write(bf.Decrypt_CBC(openBr.ReadAllBytes())); } break; case Types.BlowFishECB: using (var outFs = new BinaryWriterX(saveFile)) { var key = InputBox.Show("Input decryption key:", "Decrypt Blowfish"); if (key == String.Empty) { throw new Exception("Key can't be empty!"); } var bf = new BlowFish(key); outFs.Write(bf.Decrypt_ECB(openBr.ReadAllBytes())); } break; case Types.MTMobile: using (var outFs = new BinaryWriterX(saveFile)) { var key1 = InputBox.Show("Input 1st decryption key:", "Decrypt MTMobile"); var key2 = InputBox.Show("Input 2nd decryption key:", "Decrypt MTMobile"); if (key1 == String.Empty || key2 == String.Empty) { throw new Exception("Keys can't be empty!"); } outFs.Write(MTFramework.Decrypt(openBr.BaseStream, key1, key2)); } break; case Types.Normal: using (var outFs = new BinaryWriterX(saveFile)) { var engine = new AesEngine(); openBr.BaseStream.CopyTo(outFs.BaseStream); openBr.BaseStream.Position = 0; outFs.BaseStream.Position = 0; engine.DecryptGameNCSD(openBr.BaseStream, outFs.BaseStream); } break; case Types.CIA_shallow: using (var outFs = new BinaryWriterX(saveFile)) { var engine = new AesEngine(); openBr.BaseStream.CopyTo(outFs.BaseStream); openBr.BaseStream.Position = 0; outFs.BaseStream.Position = 0; engine.DecryptCIA(openBr.BaseStream, outFs.BaseStream, true); } break; case Types.CIA_deep: using (var outFs = new BinaryWriterX(saveFile)) { var engine = new AesEngine(); openBr.BaseStream.CopyTo(outFs.BaseStream); openBr.BaseStream.Position = 0; outFs.BaseStream.Position = 0; engine.DecryptCIA(openBr.BaseStream, outFs.BaseStream, false); } break; case Types.NCCH: using (var outFs = new BinaryWriterX(saveFile)) { var engine = new AesEngine(); openBr.BaseStream.CopyTo(outFs.BaseStream); openBr.BaseStream.Position = 0; outFs.BaseStream.Position = 0; engine.DecryptNCCH(openBr.BaseStream, outFs.BaseStream); } break; /*case Types.BOSS: * outFs.Write(engine.DecryptBOSS(openBr.ReadBytes((int)openBr.BaseStream.Length))); * break;*/ case Types.NSW_XCI: openBr.BaseStream.Position = 0; var xci_header_key = InputBox.Show("Input XCI Header Key:", "Decrypt XCI").Hexlify(); Switch.DecryptXCI(openBr.BaseStream, xci_header_key); MessageBox.Show("XCI Header and all NCA's were decrypted successfully!", "Decryption Success", MessageBoxButtons.OK); show = false; break; case Types.NSW_NCA: openBr.BaseStream.Position = 0; Switch.DecryptNCA(openBr.BaseStream, 0); MessageBox.Show("NCA was decrypted successfully!", "Decryption Success", MessageBoxButtons.OK); show = false; break; } } if (show) { MessageBox.Show($"Successfully decrypted {Path.GetFileName(openFile.Name)}.", tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); File.Delete(saveFile.Name); } }
public bool Identify(StreamInfo file, BaseReadOnlyDirectoryNode fileSystem) { using (var br = new BinaryReaderX(file.FileData, LeaveOpen)) return(br.ReadString(8) == "ARC TEST"); }
public G1T(Stream input, bool vita = false) { this.vita = vita; using (BinaryReaderX br = new BinaryReaderX(input)) { //Deciding on Endianess var magic1 = br.ReadString(4); br.ByteOrder = ByteOrder = (magic1 == "GT1G") ? ByteOrder.LittleEndian : ByteOrder.BigEndian; br.BaseStream.Position = 0; //Header header = br.ReadStruct <Header>(); //OffsetList br.BaseStream.Position = header.dataOffset; var offsetList = br.ReadMultiple <int>(header.texCount); //Meta meta = new List <Meta>(); for (int i = 0; i < header.texCount; i++) { br.BaseStream.Position = header.dataOffset + offsetList[i]; var metainfo = br.ReadStruct <Meta>(); meta.Add(metainfo); byte[] ext = null; if (metainfo.extHeader > 0) { var extSize = br.ReadInt32(); ext = br.ReadBytes(extSize - 4); } metaExt.Add(ext); //Check if format exists if (!Support.Format.ContainsKey(metainfo.format)) { throw new Exception($"Unsupported image format 0x{metainfo.format:X2}."); } IImageSwizzle swizzle = null; if (vita) { swizzle = new VitaSwizzle(metainfo.width, metainfo.height, Support.Format[metainfo.format].FormatName.Contains("DXT")); } else if (Support.Format[metainfo.format].FormatName.Contains("DXT")) { swizzle = new BlockSwizzle(metainfo.width, metainfo.height); } var setting = new ImageSettings { Width = metainfo.width, Height = metainfo.height, Swizzle = swizzle, Format = Support.Format[metainfo.format] }; settings.Add(setting); bmps.Add(Common.Load(br.ReadBytes(metainfo.width * metainfo.height * Support.Format[metainfo.format].BitDepth / 8), setting)); } } }
public static byte[] Compress(Stream input) { using (BinaryReaderX br = new BinaryReaderX(input)) { List <bool> result = new List <bool>(); List <byte> searchBuffer = new List <byte>(); for (int i = 0; i < searchBufferSize; i++) { searchBuffer.Add(0x00); } List <byte> NonePlaceholder = new List <byte>(); for (int i = 0; i < searchBufferSize; i++) { NonePlaceholder.Add(0x00); } List <byte> lookAheadBuffer = br.ReadBytes(lookAheadBufferSize).ToList(); int bk; int count = 0; while (lookAheadBuffer.Count() != 0) { byte length; byte offset; byte symbol; Search(lookAheadBuffer, searchBuffer, NonePlaceholder, out length, out offset); count++; try { symbol = lookAheadBuffer[length]; } catch { symbol = 0x24; } if (length > 0) { if (symbol == 0x24 && br.BaseStream.Length - br.BaseStream.Position > 0) { symbol = br.ReadByte(); searchBuffer.AddRange(lookAheadBuffer); searchBuffer.Add(symbol); for (int i = 0; i < lookAheadBuffer.Count(); i++) { NonePlaceholder.Add(1); } NonePlaceholder.Add(1); bk = searchBuffer.Count(); searchBuffer = GetLastElements(searchBuffer, bk - (length + 1)); NonePlaceholder = GetLastElements(NonePlaceholder, bk - (length + 1)); lookAheadBuffer.AddRange(br.ReadBytes(length + 1)); lookAheadBuffer = GetLastElements(lookAheadBuffer, lookAheadBuffer.Count() - (length + 1)); } else { searchBuffer.AddRange(GetFirstElements(lookAheadBuffer, length + 1)); for (int i = 0; i < length + 1; i++) { NonePlaceholder.Add(1); } bk = searchBuffer.Count(); searchBuffer = GetLastElements(searchBuffer, bk - (length + 1)); NonePlaceholder = GetLastElements(NonePlaceholder, bk - (length + 1)); lookAheadBuffer.AddRange(br.ReadBytes(length + 1)); lookAheadBuffer = GetLastElements(lookAheadBuffer, lookAheadBuffer.Count() - (length + 1)); } } else { bk = searchBuffer.Count(); searchBuffer = GetLastElements(searchBuffer, bk - 1); NonePlaceholder = GetLastElements(NonePlaceholder, bk - 1); byte e = lookAheadBuffer[0]; lookAheadBuffer = GetLastElements(lookAheadBuffer, lookAheadBuffer.Count() - 1); searchBuffer.Add(e); NonePlaceholder.Add(1); try { e = br.ReadByte(); lookAheadBuffer.Add(e); } catch { } } if (offset != 0) { result.Add(true); result.AddRange(GetBoolArray(offset)); result.AddRange(GetBoolArray(length)); result.AddRange(GetBoolArray(symbol)); } else { result.Add(false); result.AddRange(GetBoolArray(symbol)); } } while (result.Count() % 8 != 0) { result.Add(false); } return(GetByteArray(result)); } }
public SERIParameter ParseSERIParameter(Stream fileData, Stream names, byte[] pointers, string type, string name, int valueOffset, int valuesOffset) { switch (type) { case "s": //String names.Position = valueOffset; using (var namesB = new BinaryReaderX(names, true)) return(new String(name, namesB.ReadCStringA())); case "i": //Integer using (var br = new BinaryReaderX(fileData, true)) { var bk = br.BaseStream.Position; br.BaseStream.Position = valuesOffset + valueOffset; int IntValue = br.ReadInt32(); br.BaseStream.Position = bk; switch (name) { case "bone": case "smes": case "smat": case "tex": case "hair_length": using (var pointersB = new BinaryReaderX(new MemoryStream(pointers))) using (var namesB = new BinaryReaderX(names, true)) { pointersB.BaseStream.Position = (IntValue - 1) * 4; var tmp = pointersB.ReadInt32(); namesB.BaseStream.Position = tmp; return(new String(name, namesB.ReadCStringA())); } default: return(new Integer(name, IntValue)); } } case "b": //Boolean using (var br = new BinaryReaderX(fileData, true)) { var bk = br.BaseStream.Position; br.BaseStream.Position = valuesOffset + valueOffset; bool BooleanValue = br.ReadByte() == 1; br.BaseStream.Position = bk; return(new Boolean(name, BooleanValue)); } case "f": //Float using (var br = new BinaryReaderX(fileData, true)) { var bk = br.BaseStream.Position; br.BaseStream.Position = valuesOffset + valueOffset; float FloatValue = br.ReadSingle(); br.BaseStream.Position = bk; return(new Float(name, FloatValue)); } case "a": //Array throw new Exception($"Type {type} isn't supported!"); /*using (var br = new BinaryReaderX(fileData, true)) * { * var bk = br.BaseStream.Position; * br.BaseStream.Position = valuesOffset + valueOffset; * * var array = ParseSERIArray( * br.BaseStream, * names, * pointers, * valuesOffset, * name); * * br.BaseStream.Position = bk; * return array; * }*/ default: throw new Exception($"Type {type} is unknown!"); } }
public static byte[] Decompress(Stream instream, ByteOrder byteOrder) { using (var br = new BinaryReaderX(instream, true, byteOrder)) { #region 16-byte Header if (br.ReadString(4) != "Yay0") // "Yay0" Magic { throw new InvalidDataException("Invalid Magic, not a Yay0 File"); } int uncompressedSize = br.ReadInt32(); int linkTableOffset = br.ReadInt32(); int byteChunkAndCountModifiersOffset = br.ReadInt32(); #endregion int maskBitCounter = 0; int currentOffsetInDestBuffer = 0; int currentMask = 0; byte[] uncompressedData = new byte[uncompressedSize]; br.ByteOrder = ByteOrder.BigEndian; do { // If we're out of bits, get the next mask. if (maskBitCounter == 0) { currentMask = br.ReadInt32(); maskBitCounter = 32; } // If the next bit is set, the chunk is non-linked and just copy it from the non-link table. if (((uint)currentMask & (uint)0x80000000) == 0x80000000) { var offsetT = br.BaseStream.Position; br.BaseStream.Position = byteChunkAndCountModifiersOffset; uncompressedData[currentOffsetInDestBuffer] = br.ReadByte(); br.BaseStream.Position = offsetT; currentOffsetInDestBuffer++; byteChunkAndCountModifiersOffset++; } // Do a copy otherwise. else { // Read 16-bit from the link table var offsetT = br.BaseStream.Position; br.BaseStream.Position = linkTableOffset; ushort link = br.ReadUInt16(); br.BaseStream.Position = offsetT; linkTableOffset += 2; // Calculate the offset int offset = currentOffsetInDestBuffer - (link & 0xfff); // Calculate the count int count = link >> 12; if (count == 0) { byte countModifier; offsetT = br.BaseStream.Position; br.BaseStream.Position = byteChunkAndCountModifiersOffset; countModifier = br.ReadByte(); br.BaseStream.Position = offsetT; byteChunkAndCountModifiersOffset++; count = countModifier + 18; } else { count += 2; } // Copy the block int blockCopy = offset; for (int i = 0; i < count; i++) { uncompressedData[currentOffsetInDestBuffer] = uncompressedData[blockCopy - 1]; currentOffsetInDestBuffer++; blockCopy++; } } // Get the next bit in the mask. currentMask <<= 1; maskBitCounter--; } while (currentOffsetInDestBuffer < uncompressedSize); return(uncompressedData); } }
public SERIParameter ParseSERIArray(Stream fileData, Stream names, byte[] pointers, int valuesOffset, string name) { using (var br = new BinaryReaderX(fileData, true)) { var arrayDataType = br.ReadString(1); br.BaseStream.Position += 1; var arrayLength = br.ReadInt16(); short[] pointersA = br.ReadMultiple <short>(arrayLength).ToArray(); switch (arrayDataType) { case "s": //Of String string[] StringArray = new string[arrayLength]; for (int i = 0; i < pointersA.Length; i++) { using (var namesB = new BinaryReaderX(names, true)) { namesB.BaseStream.Position = pointersA[i]; string ItemName = namesB.ReadCStringA(); StringArray[i] = ItemName; } } return(new StringArray(name, StringArray)); case "i": //Of Integer switch (name) { case "texi": case "model": case "cloth": case "list": string[] NameArray = new string[arrayLength]; for (int i = 0; i < pointersA.Length; i++) { using (var namesB = new BinaryReaderX(names, true)) using (var pointersB = new BinaryReaderX(new MemoryStream(pointers))) { br.BaseStream.Position = valuesOffset + pointersA[i]; pointersB.BaseStream.Position = (br.ReadInt32() - 1) * 4; namesB.BaseStream.Position = pointersB.ReadInt32(); string ItemName = namesB.ReadCStringA(); NameArray[i] = ItemName; } } return(new StringArray(name, NameArray)); default: int[] IntArray = new int[arrayLength]; for (int i = 0; i < pointersA.Length; i++) { br.BaseStream.Position = valuesOffset + pointersA[i]; IntArray[i] = br.ReadInt32(); } return(new IntegerArray(name, IntArray)); } case "b": //Of Boolean bool[] BooleanArray = new bool[arrayLength]; for (int i = 0; i < pointersA.Length; i++) { br.BaseStream.Position = valuesOffset + pointersA[i]; BooleanArray[i] = br.ReadByte() == 1; } return(new BooleanArray(name, BooleanArray)); case "f": //Of Float float[] FloatArray = new float[arrayLength]; for (int i = 0; i < pointersA.Length; i++) { br.BaseStream.Position = valuesOffset + pointersA[i]; FloatArray[i] = br.ReadSingle(); } return(new FloatArray(name, FloatArray)); case "h": //Of Array SERIParameter[] NestedArray = new SERIParameter[arrayLength]; for (int i = 0; i < pointersA.Length; i++) { br.BaseStream.Position = valuesOffset + pointersA[i]; ushort Count = br.ReadUInt16(); long TypesTableOffset = valuesOffset + pointersA[i] + 2 + Count * 4; SERIParameter[] Arrays = new SERIParameter[Count]; for (int Index = 0; Index < Count; Index++) { using (var namesB = new BinaryReaderX(names, true)) { br.BaseStream.Position = valuesOffset + pointersA[i] + 2 + Index * 4; ushort NameOffset = br.ReadUInt16(); ushort ValueOffset = br.ReadUInt16(); namesB.BaseStream.Position = NameOffset; string ArrayName = namesB.ReadCStringA(); br.BaseStream.Seek(TypesTableOffset + Index, SeekOrigin.Begin); string ValueType = br.ReadString(1); Arrays[Index] = ParseSERIParameter( br.BaseStream, names, pointers, ValueType, name, ValueOffset, valuesOffset); } } NestedArray[i] = new NestedArray(null, Arrays); } return(new NestedArray(name, NestedArray)); default: throw new Exception($"Type {arrayDataType} is unknown!"); } } }
public IList <ArchiveFileInfo> Load(Stream input) { using var br = new BinaryReaderX(input, true); // Read file infos var fileCount = br.ReadInt32(); var entries = br.ReadMultiple <PckFileInfo>(fileCount); // Add files var result = new List <ArchiveFileInfo>(); foreach (var entry in entries) { br.BaseStream.Position = entry.fileOffset; // Read hash block before the file data var blockOffset = 0; var entryHashes = (List <uint>)null; var hashIdent = br.ReadInt16(); if (hashIdent == 0x64) { var hashCount = br.ReadInt16(); entryHashes = br.ReadMultiple <uint>(hashCount); blockOffset = (hashCount + 1) * 4; } // Decide filename var fileName = $"{entry.hash:X8}.bin"; // Add file var fileStream = new SubStream(input, entry.fileOffset + blockOffset, entry.fileLength - blockOffset); result.Add(new PckArchiveFileInfo(fileStream, fileName, entry, entryHashes)); } return(result); //using (var br = new BinaryReaderX(input, true)) //{ // var entries = br.ReadMultiple<Entry>(br.ReadInt32()).ToList(); // var dict = (dicts != null) ? dicts.Where(d => d.pckName == Path.GetFileNameWithoutExtension(filename)).ToList() : new List<Dict>(); // Files = entries.Select(entry => // { // br.BaseStream.Position = entry.fileOffset; // var hashes = (br.ReadInt16() == 0x64) ? br.ReadMultiple<uint>(br.ReadInt16()).ToList() : null; // int blockOffset = hashes?.Count + 1 ?? 0; // return new PckFileInfo // { // FileData = new SubStream( // input, // entry.fileOffset + blockOffset * 4, // entry.fileLength - blockOffset * 4), // FileName = (dict.Count > 0) ? // (dict[0].keyValuePairs.Find(kvp => kvp.key == entry.hash) != null ? // dict[0].keyValuePairs.Find(kvp => kvp.key == entry.hash).value : // $"0x{entry.hash:X8}.bin") : // $"0x{entry.hash:X8}.bin", // State = ArchiveFileState.Archived, // Entry = entry, // Hashes = hashes // }; // }).ToList(); //} }
/// <summary> /// Read an MTPA file into memory. /// </summary> /// <param name="input">A readable stream of an MTPA file.</param> public MTPA(Stream input) { using (var br = new BinaryReaderX(input)) { // Packet Header _packetHeader = br.ReadType <PacketHeaderX>(); // MTPA Header _mtpaHeader = br.ReadType <MTPAHeader>(); var metadataSize = _mtpaHeader.MetadataSize; // Unknown MTPA Data _mtpaHeaderData = br.ReadMultiple <int>(_mtpaHeader.MetadataSize); // Text Metadata Pointers _mtpaTextMetadataPointers = br.ReadMultiple <int>(_mtpaHeader.PointerCount); // Text Metadata if (metadataSize == 2) { _mtpaTextMetadata = br.ReadMultiple <TextMetadata>(_mtpaHeader.MetadataCount).ToList <ITextMetadata>(); } else if (metadataSize == 4) { _mtpaTextMetadata = br.ReadMultiple <TextMetadataX>(_mtpaHeader.MetadataCount).ToList <ITextMetadata>(); } // Text var textStart = (int)br.BaseStream.Position; var textEnd = _packetHeader.DataSize + _packetHeader.HeaderSize; for (var i = 0; i < _mtpaHeader.MetadataCount; i++) { var offset = textStart; var unused = false; offset += _mtpaTextMetadata[i].Offset; br.BaseStream.Position = offset; var length = br.ReadROTnInt32(); if (length == 0) { var currentOffset = _mtpaTextMetadata[i].Offset; unused = true; if (i != _mtpaHeader.MetadataCount - 1) { length = _mtpaTextMetadata[i + 1].Offset - currentOffset - 4; } else { length = textEnd - currentOffset - 4; } } var str = br.ReadROTnBytes(length); Entries.Add(new TextEntry { Name = _mtpaTextMetadata[i].ID.ToString(), EditedText = Encoding.GetEncoding("shift-jis").GetString(str).Trim('\0'), Notes = unused ? "Text length was set to zero. This line might be unused." : string.Empty }); } br.BaseStream.Position = textEnd; // ENRS _enrs = br.ReadType <PacketHeaderX>(); if (br.BaseStream.Position + _enrs.DataSize + Common.PacketHeaderXSize * 2 <= br.BaseStream.Length) { _enrsData = br.ReadBytes(_enrs.DataSize); _enrsFooter = br.ReadType <PacketHeaderX>(); } else { br.BaseStream.Position = br.BaseStream.Length - Common.PacketHeaderXSize; } // MTPA Footer _mtpaFooter = br.ReadType <PacketHeaderX>(); } }
public static FabNode Read(BinaryReaderX br) { // Read header var header = br.ReadType <FabNodeHeader>(); var result = new FabNode { _header = header }; switch (header.magic) { case "FBRC": switch (header.description) { case "BNDL": var numNode = Read(br); var count = numNode.AsInt32(); result.Nodes.Add(numNode); for (var i = 0; i < count; i++) { result.Nodes.Add(Read(br)); } break; case "TXTR": result.Nodes.Add(Read(br)); result.Nodes.Add(Read(br)); result.Nodes.Add(Read(br)); break; } break; case "USER": var offset1 = br.BaseStream.Position; br.BaseStream.Position += (header.size - 4 + 1) & ~1; result.Data = new SubStream(br.BaseStream, offset1, header.size - 4); break; case "LIST": switch (header.description) { case "FILE": result.Nodes.Add(Read(br)); result.Nodes.Add(Read(br)); break; case "META": result.Nodes.Add(Read(br)); result.Nodes.Add(Read(br)); result.Nodes.Add(Read(br)); result.Nodes.Add(Read(br)); result.Nodes.Add(Read(br)); break; case "DATA": var nextHeader = br.ReadType <FabNodeHeader>(); br.BaseStream.Position -= 0xC; // Specially handle USER node to unwrap the "actual" file data from it if (nextHeader.magic == "USER") { result.Nodes.Add(Read(br)); } else { var offset2 = br.BaseStream.Position; br.BaseStream.Position += (header.size - 4 + 1) & ~1; result.Data = new SubStream(br.BaseStream, offset2, header.size - 4); } break; } break; // By default treat content as data default: var offset = br.BaseStream.Position - 4; br.BaseStream.Position += (header.size - 4 + 1) & ~1; result._headerLength = 0x8; result.Data = new SubStream(br.BaseStream, offset, header.size); break; } return(result); }
public static byte[] Decomp(BinaryReaderX br) { // above to be restored eventually with some changes to Cetera return(Level5.Decompress(br.BaseStream)); }
private void ReadEtocTable(BinaryReaderX br, long etocOffset) { _etocTable = CpkTable.Create(br.BaseStream, etocOffset); }
static IEnumerable <Color> GetColorsFromTexture(byte[] tex, ImageSettings settings) { var format = settings.Format; using (var br = new BinaryReaderX(new MemoryStream(tex), settings.ByteOrder)) { var etc1decoder = new ETC1.Decoder(); Enum.TryParse <DXT.Formats>(format.ToString(), false, out var dxtFormat); var dxtdecoder = new DXT.Decoder(dxtFormat); Enum.TryParse <ATI.Formats>(format.ToString(), false, out var atiFormat); var atidecoder = new ATI.Decoder(atiFormat); while (true) { int a = 255, r = 255, g = 255, b = 255; switch (format) { case Format.L8: b = g = r = br.ReadByte(); break; case Format.A8: a = br.ReadByte(); break; case Format.LA44: a = br.ReadNibble() * 17; b = g = r = br.ReadNibble() * 17; break; case Format.LA88: if (settings.ByteOrder == ByteOrder.LittleEndian) { a = br.ReadByte(); b = g = r = br.ReadByte(); } else { b = g = r = br.ReadByte(); a = br.ReadByte(); } break; case Format.HL88: g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGB565: var s = br.ReadUInt16(); b = (s % 32) * 33 / 4; g = (s >> 5) % 64 * 65 / 16; r = (s >> 11) * 33 / 4; break; case Format.RGB888: b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGBA5551: var s2 = br.ReadUInt16(); a = (s2 & 1) * 255; b = (s2 >> 1) % 32 * 33 / 4; g = (s2 >> 6) % 32 * 33 / 4; r = (s2 >> 11) % 32 * 33 / 4; break; case Format.RGBA4444: a = br.ReadNibble() * 17; b = br.ReadNibble() * 17; g = br.ReadNibble() * 17; r = br.ReadNibble() * 17; break; case Format.RGBA8888: if (settings.ByteOrder == ByteOrder.LittleEndian) { a = br.ReadByte(); b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); } else { r = br.ReadByte(); g = br.ReadByte(); b = br.ReadByte(); a = br.ReadByte(); } break; case Format.RGBA1010102: var pack = br.ReadUInt32(); r = (int)((pack >> 22) / 4); g = (int)(((pack >> 12) & 0x3FF) / 4); b = (int)(((pack >> 2) & 0x3FF) / 4); a = (int)((pack & 0x3) * 85); break; case Format.ETC1: case Format.ETC1A4: yield return(etc1decoder.Get(() => { var etc1Alpha = format == Format.ETC1A4 ? br.ReadUInt64() : ulong.MaxValue; return new ETC1.PixelData { Alpha = etc1Alpha, Block = br.ReadStruct <ETC1.Block>() }; })); continue; case Format.DXT1: case Format.DXT3: case Format.DXT5: yield return(dxtdecoder.Get(() => { if (br.BaseStream.Position == br.BaseStream.Length) { return (0, 0); } var dxt5Alpha = format == Format.DXT3 || format == Format.DXT5 ? br.ReadUInt64() : 0; return (dxt5Alpha, br.ReadUInt64()); })); continue; case Format.ATI1L: case Format.ATI1A: case Format.ATI2: yield return(atidecoder.Get(() => { if (br.BaseStream.Position == br.BaseStream.Length) { return (0, 0); } return (br.ReadUInt64(), format == Format.ATI2 ? br.ReadUInt64() : 0); })); continue; case Format.L4: b = g = r = br.ReadNibble() * 17; break; case Format.A4: a = br.ReadNibble() * 17; break; case Format.PVRTC: var bmp = PVRTC.PvrtcDecompress.DecodeRgb4Bpp(tex, settings.Width); for (int y = 0; y < settings.Height; y++) { for (int x = 0; x < settings.Width; x++) { yield return(bmp.GetPixel(x, y)); } } continue; case Format.PVRTCA: bmp = PVRTC.PvrtcDecompress.DecodeRgba4Bpp(tex, settings.Width); for (int y = 0; y < settings.Height; y++) { for (int x = 0; x < settings.Width; x++) { yield return(bmp.GetPixel(x, y)); } } continue; default: throw new NotSupportedException($"Unknown image format {format}"); } yield return(Color.FromArgb(a, r, g, b)); } } }