public void Save(Stream output) { using (var bw = new BinaryWriterX(output, ByteOrder)) { bw.BaseStream.Position = HeaderLength + Header.NameSize + 1; // Section Entries if (Header.Version == Versions.Version1) { foreach (var entry in EntriesV1) { bw.WriteStruct(entry); } } else if (Header.Version == Versions.Version2) { foreach (var entry in EntriesV2) { bw.WriteStruct(entry); } } // Unknown Version 2 Section if (Header.Version == Versions.Version2) { bw.Write(UnknownV2); } // Labels uint labelSize = 0; for (var i = 0; i < Header.LabelCount; i++) { bw.WriteASCII(Names[i]); bw.Write((byte)0); labelSize += (uint)Names[i].Length + 1; } Header.LabelSize = labelSize; // Sections var textStart = bw.BaseStream.Position; foreach (var label in Labels) { bw.Write(Encoding.UTF8.GetBytes(label.Text)); bw.Write((byte)0); } Header.SectionSize = (uint)(bw.BaseStream.Position - textStart); // Header bw.BaseStream.Position = 0; bw.WriteStruct(Header); bw.WriteASCII(Name); bw.Write((byte)0); } }
public void Save(Stream output) { using (var bw = new BinaryWriterX(output)) { //Header bw.WriteASCII("XBB"); bw.Write((byte)1); bw.Write(Files.Count()); bw.BaseStream.Position = 0x20; var offset = 0x20 + Files.Sum(e => e.FileName.Length + 1 + 0x18); offset = offset + 0x7f & ~0x7f; var nameOffset = 0x20 + Files.Count() * 0x18; //FileEntries foreach (var file in Files) { bw.Write(offset); bw.Write((uint)file.FileSize); bw.Write(nameOffset); bw.Write(XbbHash.Create(file.FileName)); offset += (int)file.FileSize; offset = offset + 0x7f & ~0x7f; nameOffset += file.FileName.Length + 1; } //Hash table var files = Files.OrderBy(e => XbbHash.Create(e.FileName)).ToList(); for (int i = 0; i < files.Count(); i++) { var hash = XbbHash.Create(files[i].FileName); bw.Write(hash); bw.Write(Files.FindIndex(e => XbbHash.Create(e.FileName) == hash)); } //nameList foreach (var file in Files) { bw.WriteASCII(file.FileName); bw.Write((byte)0); } //FileData foreach (var file in Files) { bw.WriteAlignment(0x80); file.FileData.CopyTo(bw.BaseStream); } bw.WriteAlignment(0x80); } }
public void Save(Stream output) { using (var bw = new BinaryWriterX(output)) { for (var i = 0; i < Files.Count; i++) { var afi = Files[i]; if (UseFixedOffsets) { bw.BaseStream.Position = _fileOffsets[i] - Magic.Length; } bw.WriteASCII(Magic); if (afi.State == ArchiveFileState.Archived) { afi.CompressedFileData.CopyTo(bw.BaseStream); } else { bw.Write(Nintendo.Compress(afi.FileData, Nintendo.Method.LZ11)); } if (afi != Files.Last()) { bw.WriteAlignment(_alignment); } } } }
private void WriteFileEntry(BinaryWriterX bw, FileEntry entry) { bw.WriteASCII(entry.fileName.PadRight(0x16, '\0')); bw.Write(entry.nameSum); bw.Write(entry.fileOffset); bw.Write(entry.compressedSize); bw.Write(entry.uncompressedSize); }
public void Write(Stream input) { using (var bw = new BinaryWriterX(input, true)) { bw.WriteASCII(magic); bw.Write(chunkSize); bw.Write(texCount); } }
public void Save(Stream output, bool leaveOpen = false) { using (var bw = new BinaryWriterX(output, leaveOpen)) { //SARCHeader var header = new SARCHeader { dataOffset = Files.Aggregate(40 + Files.Sum(afi => usesSFNT ? afi.FileName.Length / 4 * 4 + 20 : 16), (n, afi) => Pad(n, afi.FileName)) }; bw.WriteStruct(header); // filesize is added later //SFATHeader bw.WriteStruct(new SFATHeader { nodeCount = (short)Files.Count }); //SFAT List + nameList int nameOffset = 0; int dataOffset = 0; foreach (var afi in Files) { dataOffset = Pad(dataOffset, afi.FileName); var fileLen = (int)afi.FileData.Length; var sfatEntry = new SFATEntry { nameHash = usesSFNT ? SimpleHash.Create(afi.FileName, 0x65) : Convert.ToUInt32(afi.FileName.Substring(2, 8), 16), SFNTOffset = (short)(usesSFNT ? nameOffset : 0), filenameFlags = (short)(usesSFNT ? 0x100 : 0), dataStart = dataOffset, dataEnd = dataOffset + fileLen }; bw.WriteStruct(sfatEntry); nameOffset += afi.FileName.Length / 4 + 1; dataOffset = sfatEntry.dataEnd; } bw.WriteStruct(new SFNTHeader()); if (usesSFNT) { foreach (var afi in Files) { bw.WriteASCII(afi.FileName.PadRight(afi.FileName.Length / 4 * 4 + 4, '\0')); } } bw.WriteAlignment(header.dataOffset); foreach (var afi in Files) { bw.Write(new byte[Pad((int)bw.BaseStream.Length, afi.FileName) - (int)bw.BaseStream.Length]); // padding afi.FileData.CopyTo(bw.BaseStream); } bw.BaseStream.Position = 0; header.fileSize = (int)bw.BaseStream.Length; bw.WriteStruct(header); } }
public void Save(String filename) { using (BinaryWriterX bw = new BinaryWriterX(File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Write))) { List <List <ushort> > chars = new List <List <ushort> >(); for (int i = 0; i < Labels.Count; i++) { List <ushort> list = new List <ushort>(); for (int j = 0; j < Labels[i].Text.Length; j++) { list.Add(Labels[i].Text[j]); } chars.Add(list); } //Header bw.WriteASCII("MSGD"); bw.Write(header.unk1); bw.Write(header.unk2); bw.Write(Labels.Count); bw.Write(0x20); //write offsetlist bw.BaseStream.Position = 0x20; int offset = 0; for (int i = 0; i < chars.Count; i++) { bw.Write(offset); offset += chars[i].Count * 2 + 2; } //pad to next 0x10 while (bw.BaseStream.Position % 16 != 0) { bw.BaseStream.Position += 1; } //write dataOffset long bk = bw.BaseStream.Position; bw.BaseStream.Position = 0x14; bw.Write((int)bk); bw.BaseStream.Position = bk; //write obfuscated text for (int i = 0; i < chars.Count; i++) { for (int j = 0; j < chars[i].Count; j++) { bw.Write((ushort)(chars[i][j] ^ 0xff73)); } bw.Write((ushort)0xff73); } } }
public void Save(string filename) { using (BinaryWriterX bw = new BinaryWriterX(File.Create(filename))) { settings.Width = bmps[0].Width; settings.Height = bmps[0].Height; var texData = Kontract.Image.Common.Save(bmps[0], settings); var palData = format.paletteBytes; if (palData.Length > 0x200) { throw new System.Exception("Your image contains more than 256 colors. The format doesn't allow more than 256 colors."); } //Header bw.Write((short)bmps[0].Width); bw.Write((short)bmps[0].Height); var entry = entries.Find(e => e.magic == "nns_frmt"); bw.WriteASCII(entry.magic); bw.Write(entry.nnsSize); bw.Write(entry.data); //image data bw.WriteASCII("nns_txel"); bw.Write(texData.Length + 0xc); bw.Write(texData); //palette data bw.WriteASCII("nns_pcol"); bw.Write(0x20c); bw.Write(palData); bw.WritePadding(0x20c - (palData.Length + 0xc), 0xff); //end tag bw.WriteASCII("nns_endb"); bw.Write(0xc); } }
public void Save(Stream binOutput, Stream arcOutput) { using (var bw = new BinaryWriterX(binOutput)) { bw.WriteStruct(Header); var filenameOffsets = bw.BaseStream.Position; var fileOffsets = Header.FileCount * 0x10 + filenameOffsets; var filenamesOffset = (Header.FileCount * 0x4 + fileOffsets + 15) & ~15; // Files using (var bw2 = new BinaryWriterX(arcOutput)) { bw2.BaseStream.Position = ArcStartOffset; for (var i = 0; i < Files.Count; i++) { Files[i].Entry.Offset = (uint)bw2.BaseStream.Position; Files[i].Entry.FileSize = (uint)Files[i].FileSize; Files[i].FileData.CopyTo(bw2.BaseStream); bw2.WriteAlignment(); } } // Filenames bw.BaseStream.Position = filenamesOffset; for (var i = 0; i < Header.FileCount; i++) { Entries[i].FilenameOffset = (uint)bw.BaseStream.Position; bw.WriteASCII(Entries[i].Filename); bw.Write((byte)0x0); bw.WriteAlignment(); } // Filename Offsets bw.BaseStream.Position = filenameOffsets; for (var i = 0; i < Header.FileCount; i++) { var entry = Entries[i]; bw.Write(entry.FilenameOffset); bw.Write(entry.FileSize); bw.Write(entry.Unk1); bw.Write(entry.Unk2); } // File Offsets bw.BaseStream.Position = fileOffsets; for (var i = 0; i < Header.FileCount; i++) { bw.Write(Entries[i].Offset); } } }
public void Save(Stream output) { using (var bw = new BinaryWriterX(output, true)) { bw.Write(Unk1); bw.Write(Unk2); NameSize = (byte)(Name.Length + 1); bw.Write(NameSize); bw.WriteASCII(Name); bw.Write((byte)0); bw.WriteAlignment(4); bw.Write(Unk3); } }
public void Save(Stream output) { var headerSize = 0x10; var entrySize = 0x28; using (var bw = new BinaryWriterX(output)) { bw.WriteStruct(Header); // Strings bw.BaseStream.Position = headerSize + Header.EntryCount * entrySize; var strEntries = Entries.Where(e => e.Offset > 0).ToList(); var offset = (int)bw.BaseStream.Position; for (var i = 0; i < strEntries.Count; i++) { var entry = strEntries[i]; if (entry.Label == "<label>") { bw.WriteASCII(Strings[i].Text); bw.Write((byte)0x0); } else { bw.Write(Encoding.Unicode.GetBytes(Strings[i].Text)); bw.Write((byte)0x0); bw.Write((byte)0x0); } bw.WriteAlignment(4); entry.Offset = offset; offset = (int)bw.BaseStream.Position; } // Odd extra bytes bw.Write(0); bw.Write((byte)0x0); // Entries bw.BaseStream.Position = headerSize; foreach (var entry in Entries) { bw.WriteStruct(entry); } } }
public void Save(String filename) { Color[] colors = TmxSupport.GetPalette(bmp); byte[] picData = null; byte[] paletteData = null; if (colors.Length == 16) { picData = TmxSupport.CreateIndexed4(bmp, colors); paletteData = TmxSupport.GetPaletteBytes(colors); header.imageFormat = TMXPixelFormat.PSMT4; header.paletteFormat = TMXPixelFormat.PSMCT32; } else if (colors.Length == 256) { picData = TmxSupport.CreateIndexed8(bmp, colors); paletteData = TmxSupport.GetPaletteBytes(colors); header.imageFormat = TMXPixelFormat.PSMT8; header.paletteFormat = TMXPixelFormat.PSMCT32; } else { picData = TmxSupport.Create32(bmp); header.imageFormat = TMXPixelFormat.PSMCT32; } header.height = (ushort)bmp.Height; header.width = (ushort)bmp.Width; using (BinaryWriterX bw = new BinaryWriterX(File.Create(filename))) { bw.WriteStruct(header); bw.WriteASCII(comment); bw.BaseStream.Position = 0x40; if (paletteData != null) { bw.Write(paletteData); } bw.Write(picData); } }
private void WriteLBL1(BinaryWriterX bw) { // Calculate Section Size uint newSize = sizeof(uint); // Number of Groups newSize = LBL1.Groups.Aggregate(newSize, (current, grp) => current + sizeof(uint) + sizeof(uint)); newSize = LBL1.Labels.Aggregate(newSize, (current, lbl) => current + (uint)(sizeof(byte) + lbl.Name.Length + sizeof(uint))); LBL1.Section.Size = newSize; // Calculate Group Offsets uint runningTotal = 0; for (var i = 0; i < LBL1.Groups.Count; i++) { LBL1.Groups[i].Offset = LBL1.NumberOfGroups * sizeof(uint) * 2 + sizeof(uint) + runningTotal; runningTotal = LBL1.Labels.Where(lbl => lbl.Checksum == i).Aggregate(runningTotal, (current, lbl) => current + (uint)(sizeof(byte) + lbl.Name.Length + sizeof(uint))); } // Section bw.WriteStruct(LBL1.Section); bw.Write(LBL1.NumberOfGroups); // Groups foreach (var group in LBL1.Groups) { bw.WriteStruct(group); } // Labels foreach (var group in LBL1.Groups) { foreach (var label in LBL1.Labels) { if (label.Checksum == LBL1.Groups.IndexOf(group)) { bw.Write(Convert.ToByte(Encoding.ASCII.GetBytes(label.Name).Length)); bw.WriteASCII(label.Name); bw.Write(label.Index); } } } bw.WriteAlignment(_paddingChar); }
public void Save(Stream output) { using (var bw = new BinaryWriterX(output)) { //Header bw.WriteStruct(partHeader); bw.WriteStruct(header); //Files bw.BaseStream.Position = Files[0].entry.offset; foreach (var file in Files) { file.entry.offset = (uint)bw.BaseStream.Position; file.entry.size = (uint)file.FileSize; bw.WriteAlignment(); file.FileData.CopyTo(bw.BaseStream); } //Entries bw.BaseStream.Position = header.entryListOffset; foreach (var file in Files) { bw.WriteStruct(file.entry); } //NameLength bw.BaseStream.Position = header.nameOffset; var nameOffset = (uint)bw.BaseStream.Length; foreach (var file in Files) { bw.Write(nameOffset); nameOffset += (uint)Encoding.ASCII.GetByteCount(file.FileName) + 1; } //Names bw.BaseStream.Position = bw.BaseStream.Length; foreach (var file in Files) { bw.WriteASCII(file.FileName); bw.Write((byte)0); } } }
public void Save(Stream output) { using (BinaryWriterX bw = new BinaryWriterX(output)) { var files = Files.OrderBy(x => x.hash); //entryList and FileData uint offset = 0xc + (uint)files.Count() * 0xc; while (offset % 0x80 != 0) { offset++; } bw.BaseStream.Position = 0xc; foreach (var file in files) { bw.Write(offset); bw.Write((uint)file.FileSize); bw.Write(file.hash); long bk = bw.BaseStream.Position; bw.BaseStream.Position = offset; file.FileData.CopyTo(bw.BaseStream); while (bw.BaseStream.Position % 0x80 != 0) { bw.Write((byte)0xac); } offset = (uint)bw.BaseStream.Position; bw.BaseStream.Position = bk; } while (bw.BaseStream.Position % 0x80 != 0) { bw.Write((byte)0xac); } //Header bw.BaseStream.Position = 0; bw.WriteASCII("ARCV"); bw.Write(Files.Count); bw.Write((uint)bw.BaseStream.Length); } }
public void Save(Stream hpi, Stream hpb) { using (hpb) using (var bw = new BinaryWriterX(hpi)) { // HPI Header bw.WriteStruct(new HpiHeader { hashCount = (short)HashSlotCount, entryCount = Files.Count }); int stringOffset = 0; foreach (var afi in Files) { afi.Entry.stringOffset = stringOffset; afi.WriteToHpb(hpb); stringOffset += afi.FileName.Length + 1; } // Hash List var lookup = Files.ToLookup(e => SimpleHash.Create(e.FileName, PathHashMagic, HashSlotCount)); for (int i = 0, offset = 0; i < HashSlotCount; i++) { var count = lookup[(uint)i].Count(); bw.WriteStruct(new HashEntry { entryOffset = (short)offset, entryCount = (short)count }); offset += count; } // Entry List foreach (var afi in lookup.OrderBy(g => g.Key).SelectMany(g => g)) { bw.WriteStruct(afi.Entry); } // String Table foreach (var afi in Files) { bw.WriteASCII(afi.FileName + '\0'); } } }
private bool WriteATO1(BinaryWriterX bw) { bool result = false; try { bw.WriteASCII(ATO1.Identifier); bw.Write(ATO1.SectionSize); bw.Write(ATO1.Padding1); bw.Write(ATO1.Unknown2); result = true; } catch (Exception) { result = false; } return(result); }
public void Save(string filename, Bitmap bitmap) { using (BinaryWriterX bw = new BinaryWriterX(File.Create(filename))) { byte[] pic = Common.Save(bitmap, settings); header.width = bitmap.Width; header.height = bitmap.Height; header.dataSize = pic.Length; bw.WriteStruct(header); bw.Write(0x80); bw.Write(texInfo.unk1); bw.WriteASCII(texInfo.name); bw.Write((byte)0); bw.BaseStream.Position = 0x80; bw.Write(pic); } }
public void Save(Stream output) { using (var bw = new BinaryWriterX(output)) { foreach (var afi in Files) { bw.WriteASCII(Magic); if (afi.State == ArchiveFileState.Archived) { afi.CompressedFileData.CopyTo(bw.BaseStream); } else { bw.Write(Nintendo.Compress(afi.FileData, Nintendo.Method.LZ11)); } if (afi != Files.Last()) { bw.WriteAlignment(_alignment); } } } }
public void Save(string filename) { using (var bw = new BinaryWriterX(File.Create(filename))) { //To change //Header - fileSize bw.BaseStream.Position = 4; //TextEntries uint textDataOffset = 2; for (int i = 0; i < Labels.Count; i++) { bw.WriteASCII(Labels[i].Name); for (int j = 8 - Labels[i].Name.Length; j > 0; j--) { bw.Write((byte)0); } bw.Write(textDataOffset); textDataOffset += (uint)Encoding.Unicode.GetBytes(Labels[i].Text).Length + 2; } //Texts bw.BaseStream.Position += 2; for (int i = 0; i < Labels.Count; i++) { var text = Encoding.Unicode.GetBytes(Labels[i].Text); bw.Write((ushort)text.Length); bw.Write(text); } bw.BaseStream.Position = 4 + Labels.Count * 0xc; bw.Write((ushort)(bw.BaseStream.Length - (4 + Labels.Count * 0xc))); //Header bw.BaseStream.Position = 0; header.fileSize = (ushort)bw.BaseStream.Length; bw.WriteStruct(header); } }
private void SaveSystemGar(Stream input) { int Align(int value, int align) => value + (align - 1) & ~(align - 1); using (var bw = new BinaryWriterX(input)) { var files = Files.OrderBy(x => x.ext.Length).ToList(); //get Extension and their count Dictionary <string, int> exts = new Dictionary <string, int>(); foreach (var file in files) { var ext = Path.GetExtension(file.FileName).Replace(".", ""); if (!exts.ContainsKey(ext)) { exts.Add(ext, 1); } else { exts[ext]++; } } //get offsets int chunkExtNameOffset = _header.chunkEntryOffset + (exts.Count + 1) * 0x20; int chunkSubTableOffset = Align(chunkExtNameOffset + Encoding.ASCII.GetByteCount("unknown\0") + exts.Aggregate(0, (a, b) => a + Encoding.ASCII.GetByteCount(b.Key) + 1), 4); int chunkInfoOffset = chunkSubTableOffset + sysEntriesSubTable.Length; int chunkInfoNameOffset = chunkInfoOffset + Files.Count * 0x10; int dataOffset = Align(chunkInfoNameOffset + Files.Aggregate(0, (a, b) => a + Encoding.ASCII.GetByteCount(Path.GetFileName(b.FileName)) + 1), 0x80); bw.BaseStream.Position = 0x20; //Write chunkEntries int localChunkNameOffset = chunkExtNameOffset; //Add "unknown" chunk Entry bw.Write(0); bw.Write(0x4); bw.Write(0xFFFFFFFF); bw.Write(localChunkNameOffset); bw.Write(0xFFFFFFFF); bw.BaseStream.Position += 0xC; localChunkNameOffset += Encoding.ASCII.GetByteCount("unknown\0"); //Add all other chunk entries int filesAdded = 0; foreach (var ext in exts) { bw.Write(ext.Value); bw.Write(sysEntries.FirstOrDefault(x => x.name == ext.Key)?.unk1 ?? 0x4); bw.Write(filesAdded); bw.Write(localChunkNameOffset); bw.Write(sysEntries.FirstOrDefault(x => x.name == ext.Key)?.subTableOffset ?? 0x0); bw.BaseStream.Position += 0xC; filesAdded += ext.Value; localChunkNameOffset += Encoding.ASCII.GetByteCount(ext.Key) + 1; } //Add chunk Extensions bw.WriteASCII("unknown\0"); foreach (var ext in exts) { bw.WriteASCII(ext.Key + "\0"); } bw.WriteAlignment(4); //Add subtable bw.Write(sysEntriesSubTable); //Write chunkInfos and Files var localChunkInfoOffset = chunkInfoOffset; var localChunkInfoNameOffset = chunkInfoNameOffset; var localDataOffset = dataOffset; foreach (var ext in exts) { var filesToAdd = Files.Where(x => x.ext == ext.Key); foreach (var toAdd in filesToAdd) { bw.BaseStream.Position = localChunkInfoOffset; bw.Write((int)toAdd.FileSize); bw.Write(localDataOffset); bw.Write(localChunkInfoNameOffset); bw.Write(0xFFFFFFFF); bw.BaseStream.Position = localChunkInfoNameOffset; bw.WriteASCII(Path.GetFileNameWithoutExtension(toAdd.FileName) + "\0"); bw.BaseStream.Position = localDataOffset; toAdd.FileData.CopyTo(bw.BaseStream); localDataOffset += (int)toAdd.FileSize; localChunkInfoNameOffset += Encoding.ASCII.GetByteCount(Path.GetFileNameWithoutExtension(toAdd.FileName)) + 1; localChunkInfoOffset += 0x10; } } //Header bw.BaseStream.Position = 0; _header.fileSize = (uint)bw.BaseStream.Length; _header.fileChunks = (short)(exts.Count + 1); _header.fileCount = (short)files.Count; _header.chunkInfOffset = chunkInfoOffset; _header.offset3 = dataOffset; bw.WriteStruct(_header); } }
private bool WriteTXT2(BinaryWriterX bw) { bool result = false; try { // Calculate Section Size uint newSize = TXT2.NumberOfStrings * sizeof(uint) + sizeof(uint); for (int i = 0; i < TXT2.NumberOfStrings; i++) { newSize += (uint)GetBytes(TXT2.Strings[i].Text).Length + (uint)(Header.EncodingByte == EncodingByte.UTF8 ? 1 : 2); } bw.WriteASCII(TXT2.Identifier); bw.Write(newSize); bw.Write(TXT2.Padding1); long startOfStrings = bw.BaseStream.Position; bw.Write(TXT2.NumberOfStrings); List <uint> offsets = new List <uint>(); uint offsetsLength = TXT2.NumberOfStrings * sizeof(uint) + sizeof(uint); uint runningTotal = 0; for (int i = 0; i < TXT2.NumberOfStrings; i++) { offsets.Add(offsetsLength + runningTotal); runningTotal += (uint)GetBytes(TXT2.Strings[i].Text).Length + (uint)(Header.EncodingByte == EncodingByte.UTF8 ? 1 : 2); } for (int i = 0; i < TXT2.NumberOfStrings; i++) { bw.Write(offsets[i]); } for (int i = 0; i < TXT2.NumberOfStrings; i++) { byte[] text = GetBytes(TXT2.Strings[i].Text); if (Header.EncodingByte == EncodingByte.UTF8) { bw.Write(text); bw.Write((byte)0x0); } else { if (Header.ByteOrderMark[0] == 0xFF) { bw.Write(text); } else { for (int j = 0; j < text.Length; j += 2) { bw.Write(text[j + 1]); bw.Write(text[j]); } } bw.Write(new byte[] { 0x0, 0x0 }); } } PaddingWrite(bw); result = true; } catch (Exception) { result = false; } return(result); }
private bool WriteLBL1(BinaryWriterX bw) { bool result = false; try { // Calculate Section Size uint newSize = sizeof(uint); foreach (Group grp in LBL1.Groups) { newSize += (uint)(sizeof(uint) + sizeof(uint)); } foreach (Label lbl in LBL1.Labels) { newSize += (uint)(sizeof(byte) + lbl.Name.Length + sizeof(uint)); } // Calculate Group Offsets uint offsetsLength = LBL1.NumberOfGroups * sizeof(uint) * 2 + sizeof(uint); uint runningTotal = 0; for (int i = 0; i < LBL1.Groups.Count; i++) { LBL1.Groups[i].Offset = offsetsLength + runningTotal; foreach (Label lbl in LBL1.Labels) { if (lbl.Checksum == i) { runningTotal += (uint)(sizeof(byte) + lbl.Name.Length + sizeof(uint)); } } } // Write bw.WriteASCII(LBL1.Identifier); bw.Write(newSize); bw.Write(LBL1.Padding1); bw.Write(LBL1.NumberOfGroups); foreach (Group grp in LBL1.Groups) { bw.Write(grp.NumberOfLabels); bw.Write(grp.Offset); } foreach (Group grp in LBL1.Groups) { foreach (Label lbl in LBL1.Labels) { if (lbl.Checksum == LBL1.Groups.IndexOf(grp)) { bw.Write(Convert.ToByte(lbl.Length)); bw.WriteASCII(lbl.Name); bw.Write(lbl.Index); } } } PaddingWrite(bw); result = true; } catch (Exception) { result = false; } return(result); }
// Saving public bool Save(string filename) { bool result = false; try { using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None)) { BinaryWriterX bw = new BinaryWriterX(fs); // Byte Order bw.ByteOrder = Header.ByteOrderMark[0] > Header.ByteOrderMark[1] ? ByteOrder.LittleEndian : ByteOrder.BigEndian; // Header bw.WriteASCII(Header.Identifier); bw.Write(Header.ByteOrderMark); bw.Write(Header.Unknown1); bw.Write((byte)Header.EncodingByte); bw.Write(Header.Unknown2); bw.Write(Header.NumberOfSections); bw.Write(Header.Unknown3); bw.Write(Header.FileSize); bw.Write(Header.Unknown4); foreach (string section in SectionOrder) { if (section == "LBL1") { WriteLBL1(bw); } else if (section == "NLI1") { WriteNLI1(bw); } else if (section == "ATO1") { WriteATO1(bw); } else if (section == "ATR1") { WriteATR1(bw); } else if (section == "TSY1") { WriteTSY1(bw); } else if (section == "TXT2") { WriteTXT2(bw); } } // Update FileSize long fileSize = bw.BaseStream.Position; bw.BaseStream.Seek(Header.FileSizeOffset, SeekOrigin.Begin); bw.Write((uint)fileSize); bw.Close(); result = true; } } catch (Exception) { } return(result); }
public void Save(Stream output) { using (var bw = new BinaryWriterX(output)) { var files = Files.OrderBy(x => x.ext.Length).ToList(); //get Extension and there count List <string> exts = new List <string>(); List <int> extsCount = new List <int>(); foreach (var file in files) { if (!exts.Contains(Path.GetExtension(file.FileName).Split('.')[1])) { exts.Add(Path.GetExtension(file.FileName).Split('.')[1]); extsCount.Add(1); } else { extsCount[exts.FindIndex(x => x == Path.GetExtension(file.FileName).Split('.')[1])]++; } } //get offsets int chunkIDOffset = 0x20 + (exts.Count + 1) * 0x10; int chunkInfOffset = chunkIDOffset + 8 + files.Count * 0x4; for (int i = 0; i < exts.Count; i++) { chunkInfOffset += (exts[i].Length + 1); while (chunkInfOffset % 4 != 0) { chunkInfOffset++; } } int nameOffset = chunkInfOffset + files.Count * 0xc; int offListOffset = nameOffset; for (int i = 0; i < files.Count; i++) { offListOffset += files[i].FileName.Length + 1; offListOffset += files[i].FileName.Split('.')[0].Length + 1; while (offListOffset % 4 != 0) { offListOffset++; } } int dataOffset = offListOffset + files.Count * 0x4; bw.BaseStream.Position = 0x20; //write chunkEntries int tmp = chunkIDOffset; for (int i = 0; i <= exts.Count; i++) { if (i == 0) { bw.Write(0); bw.Write(0xFFFFFFFF); bw.Write(tmp); bw.Write(0xFFFFFFFF); tmp += 8; } else { bw.Write(extsCount[i - 1]); bw.Write(tmp); bw.Write(tmp + extsCount[i - 1] * 4); bw.Write(0xFFFFFFFF); var padding = 0; while ((exts[i - 1].Length + 1 + padding) % 4 != 0) { padding++; } tmp += extsCount[i - 1] * 4 + exts[i - 1].Length + 1 + padding; } } //write chunkIDs and magics int id = 0; for (int i = 0; i <= exts.Count; i++) { if (i == 0) { bw.WriteASCII("unknown"); bw.Write((byte)0); } else { for (int j = 0; j < extsCount[i - 1]; j++) { bw.Write(id++); } bw.WriteASCII(exts[i - 1]); bw.Write((byte)0); while (bw.BaseStream.Position % 4 != 0) { bw.BaseStream.Position++; } } } //write chunkInfos tmp = nameOffset; foreach (var file in files) { bw.Write((uint)file.FileSize); bw.Write(tmp + file.FileName.Length + 1); bw.Write(tmp); tmp += file.FileName.Length + 1 + file.FileName.Split('.')[0].Length + 1; while (tmp % 4 != 0) { tmp++; } } //write names foreach (var file in files) { bw.WriteASCII(file.FileName); bw.Write((byte)0); bw.WriteASCII(file.FileName.Split('.')[0]); bw.Write((byte)0); while (bw.BaseStream.Position % 4 != 0) { bw.BaseStream.Position++; } } //write offsets tmp = dataOffset; foreach (var file in files) { bw.Write(tmp); tmp += (int)file.FileSize; } //write fileData foreach (var file in files) { file.FileData.CopyTo(bw.BaseStream); } //Header bw.BaseStream.Position = 0; header.fileSize = (uint)bw.BaseStream.Length; header.fileChunks = (short)(exts.Count + 1); header.fileCount = (short)files.Count; header.chunkInfOffset = chunkInfOffset; header.offsetList = offListOffset; bw.WriteStruct(header); } }
public void Save(Stream input, bool leaveOpen) { using (BinaryWriterX bw = new BinaryWriterX(input, leaveOpen)) { //check original sizes CheckOriginalSizes(); //Write CTPK Header bw.WriteStruct(header); bw.BaseStream.Position = 0x20; //Write TexEntries foreach (var entry in entries) { bw.WriteStruct(entry.texEntry); } //Write dataSizes foreach (var entry in entries) { foreach (var size in entry.dataSizes) { bw.Write(size); } } //Write names foreach (var entry in entries) { bw.WriteASCII(entry.name + "\0"); } //Write hashes bw.BaseStream.Position = (bw.BaseStream.Position + 0x3) & ~0x3; List <HashEntry> hash = entries.Select(c => c.hash).OrderBy(c => c.crc32).ToList(); foreach (var entry in hash) { bw.WriteStruct(entry); } //Write mipmapInfo foreach (var entry in entries) { bw.WriteStruct(entry.mipmapEntry); } //Write bitmaps bw.BaseStream.Position = header.texSecOffset; var index = 0; foreach (var entry in entries) { var settings = new ImageSettings { Width = bmps[index].Width, Height = bmps[index].Height, Format = Support.CTRFormat[entry.texEntry.imageFormat], Swizzle = new CTRSwizzle(bmps[index].Width, bmps[index].Height) }; bw.Write(Common.Save(bmps[index++], settings)); if (entry.texEntry.mipLvl > 1) { for (int i = 1; i < entry.texEntry.mipLvl; i++) { settings = new ImageSettings { Width = bmps[index].Width << i, Height = bmps[index].Height << i, Format = Support.CTRFormat[entry.mipmapEntry.mipmapFormat], Swizzle = new CTRSwizzle(bmps[index].Width << i, bmps[index].Height << i) }; bw.Write(Common.Save(bmps[index++], settings)); } } } } }
// Manipulation //TODO: Manipulation functions // Saving public bool Save(string filename) { bool result = false; try { using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None)) { BinaryWriterX bw = new BinaryWriterX(fs); // Header bw.WriteASCII(Header.Identifier + "\0"); bw.Write(Header.Unknown1); bw.Write(Header.Unknown2); bw.Write(Header.Unknown3); bw.Write(Header.NumberOfLabels); bw.Write(Header.NumberOfOffsets); bw.Write(Header.Unknown4); long dataSizeOffset = bw.BaseStream.Position; bw.Write(Header.DataSize); bw.Write(Header.NameLength); bw.WriteASCII(Header.Name + "\0"); foreach (Label label in Labels) { bw.Write(label.ID); bw.Write(label.Unknown1); bw.Write(label.Unknown2); bw.Write(label.Unknown3); bw.Write(label.Unknown4); } bw.Write(Unknown1024); // Read in the label names foreach (Label label in Labels) { bw.WriteASCII(label.Name); bw.Write(new byte[] { 0x0 }); } // Read in the text data uint dataSize = 0; foreach (Label label in Labels) { bw.Write(label.Text); bw.Write(new byte[] { 0x0 }); dataSize += (uint)label.Text.Length + 1; } // Update DataSize bw.BaseStream.Seek(dataSizeOffset, SeekOrigin.Begin); bw.Write(dataSize); bw.Close(); result = true; } } catch (Exception) { } return(result); }
public void Save(Stream output) { int Pad128(int n) => (n + 127) & ~127; using (var bw = new BinaryWriterX(output)) { //get nameList Length int nameListLength = (Files.Sum(afi => afi.FileName.Length + 1) + 3) & ~3; //Offsets int nameOffset = (Files.Count + 1) * 0x20 + Files.Count * 0x4; //Header bw.WriteStruct(new Header { texCount = (short)Files.Count, texSecOffset = Pad128(nameOffset + nameListLength + Files.Count * 12), texSecSize = (int)Files.Sum(afi => afi.FileSize), crc32SecOffset = nameOffset + nameListLength, texInfoOffset = nameOffset + nameListLength + Files.Count * 0x8 }); //entryList int dataOffset = 0; foreach (var afi in Files) { dataOffset = Pad128(dataOffset); var entry = afi.Entry; entry.texDataSize = (int)afi.FileData.Length; entry.nameOffset = nameOffset; entry.texOffset = dataOffset; bw.WriteStruct(entry); nameOffset += afi.FileName.Length + 1; dataOffset += (int)afi.FileSize; } //texInfo 1 List foreach (var afi in Files) { bw.Write((int)afi.FileData.Length); } //nameList foreach (var afi in Files) { bw.WriteASCII(afi.FileName + '\0'); } while (bw.BaseStream.Position % 4 != 0) { bw.BaseStream.Position++; } //crc32List foreach (var afi in Files) { bw.Write(afi.hashEntry.crc32); bw.Write(afi.hashEntry.entryNr); } //texInfo 2 List foreach (var afi in Files) { bw.Write(afi.texInfo); } //Write data foreach (var afi in Files) { bw.Write(new byte[Pad128((int)bw.BaseStream.Length) - (int)bw.BaseStream.Length]); afi.FileData.CopyTo(bw.BaseStream); } } }
public static byte[] Compress(Stream instream) { if (instream == null) { throw new Exception("File should not be null!"); } if (instream.Length == 0) { throw new Exception("File should not be empty!"); } using (var bw = new BinaryWriterX(new MemoryStream((int)instream.Length))) { #region Yaz0 Header bw.WriteASCII("Yaz0"); bw.Write((int)instream.Length); bw.Write((long)0); #endregion int srcPos = 0; int dstPos = 0; byte[] dst = new byte[24]; // 8 codes * 3 bytes maximum per code. int validBitCount = 0; byte curCodeByte = 0; byte[] src = new BinaryReaderX(instream, true).ReadAllBytes(); while (srcPos < src.Length) { int numBytes, matchPos; NintendoYaz0Encode(src, srcPos, out numBytes, out matchPos); if (numBytes < 3) { // Straight Copy dst[dstPos] = src[srcPos]; srcPos++; dstPos++; // Set flag for straight copy curCodeByte |= (byte)(0x80 >> validBitCount); } else { // RLE part uint dist = (uint)(srcPos - matchPos - 1); byte byte1, byte2, byte3; // Requires a 3 byte encoding if (numBytes >= 0x12) { byte1 = (byte)(0 | (dist >> 8)); byte2 = (byte)(dist & 0xFF); dst[dstPos++] = byte1; dst[dstPos++] = byte2; // Maximum run length for 3 byte encoding. if (numBytes > 0xFF + 0x12) { numBytes = 0xFF + 0x12; } byte3 = (byte)(numBytes - 0x12); dst[dstPos++] = byte3; } // 2 byte encoding else { byte1 = (byte)((uint)((numBytes - 2) << 4) | (dist >> 8)); byte2 = (byte)(dist & 0xFF); dst[dstPos++] = byte1; dst[dstPos++] = byte2; } srcPos += numBytes; } validBitCount++; // Write 8 codes if we've filled a block if (validBitCount == 8) { // Write the code byte bw.Write(curCodeByte); // And then any bytes in the dst buffer. for (int i = 0; i < dstPos; i++) { bw.Write(dst[i]); } //output.Flush(); curCodeByte = 0; validBitCount = 0; dstPos = 0; } } // If we didn't finish off on a whole byte, add the last code byte. if (validBitCount > 0) { // Write the code byte bw.Write(curCodeByte); // And then any bytes in the dst buffer. for (int i = 0; i < dstPos; i++) { bw.Write(dst[i]); } curCodeByte = 0; validBitCount = 0; dstPos = 0; } return(new BinaryReaderX(bw.BaseStream).ReadAllBytes()); } }
public bool Save(string filename) { bool result = false; try { using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None)) { BinaryWriterX bw = new BinaryWriterX(fs); // Header bw.WriteASCII(Header.Identifier); uint fileSizeOffset = (uint)bw.BaseStream.Position; bw.Write(Header.FileSize); bw.Write(Header.NumberOfEntries); bw.Write(Header.Version); uint labelsOffset = 0; if (Header.Version == 0x11) { bw.Write(Header.HasLabels); labelsOffset = (uint)bw.BaseStream.Position; bw.Write(Header.LabelsOffset - Header.Size); } uint entryStart = Header.Size; uint textStart = (uint)bw.BaseStream.Position + (uint)(Labels.Count * 2 * 8); // Text bw.BaseStream.Seek(textStart, SeekOrigin.Begin); for (int i = 0; i < Header.NumberOfEntries; i++) { Label label = Labels[i]; label.TextOffset = (uint)bw.BaseStream.Position - Header.Size; bw.Write(FileEncoding.GetBytes(label.Text)); bw.Write(new byte[] { 0x0, 0x0 }); } // Extra for (int i = 0; i < Header.NumberOfEntries; i++) { Label label = Labels[i]; label.ExtraOffset = (uint)bw.BaseStream.Position - Header.Size; bw.Write(FileEncoding.GetBytes(label.Extra)); bw.Write(new byte[] { 0x0, 0x0 }); } // Pad to the nearest 8 bytes PaddingWrite(bw, Header.Version == 0x11 ? 8 : 4); // Set label offset variables uint labelsOffsets = (uint)bw.BaseStream.Position; uint labelsStart = (uint)bw.BaseStream.Position + (uint)(Labels.Count * 4); // Grab the new LabelsOffset if (Header.HasLabels == 0x0101) { Header.LabelsOffset = (uint)bw.BaseStream.Position - Header.Size; } else { Header.LabelsOffset = 0; } // Text Offsets bw.BaseStream.Seek(entryStart, SeekOrigin.Begin); for (int i = 0; i < Header.NumberOfEntries; i++) { Label label = Labels[i]; bw.Write(label.TextID); bw.Write(label.TextOffset); } // Extra Offsets for (int i = 0; i < Header.NumberOfEntries; i++) { Label label = Labels[i]; bw.Write(label.ExtraID); bw.Write(label.ExtraOffset); } // Labels if (Header.HasLabels == 0x0101) { // Label Names bw.BaseStream.Seek(labelsStart, SeekOrigin.Begin); for (int i = 0; i < Header.NumberOfEntries; i++) { Label label = Labels[i]; label.NameOffset = (uint)bw.BaseStream.Position - Header.Size; bw.WriteASCII(label.Name); bw.Write((byte)0x0); } // Pad to the nearest 8 bytes PaddingWrite(bw, Header.Version == 0x11 ? 8 : 4); // Label Offsets bw.BaseStream.Seek(labelsOffsets, SeekOrigin.Begin); for (int i = 0; i < Header.NumberOfEntries; i++) { bw.Write(Labels[i].NameOffset); } // Update LabelsOffset bw.BaseStream.Seek(labelsOffset, SeekOrigin.Begin); bw.Write(Header.LabelsOffset); } // Update FileSize Header.FileSize = (uint)bw.BaseStream.Length; bw.BaseStream.Seek(fileSizeOffset, SeekOrigin.Begin); bw.Write(Header.FileSize); bw.Close(); } result = true; } catch (Exception) { } return(result); }