예제 #1
0
        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);
            }
        }
예제 #2
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);
            }
        }
예제 #3
0
파일: 3DSLZ.cs 프로젝트: wabberz/Kuriimu
 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);
             }
         }
     }
 }
예제 #4
0
 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);
 }
예제 #5
0
 public void Write(Stream input)
 {
     using (var bw = new BinaryWriterX(input, true))
     {
         bw.WriteASCII(magic);
         bw.Write(chunkSize);
         bw.Write(texCount);
     }
 }
예제 #6
0
        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);
            }
        }
예제 #7
0
파일: MDT.cs 프로젝트: getov/Kuriimu
        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);
                }
            }
        }
예제 #8
0
파일: CTGD.cs 프로젝트: wabberz/Kuriimu
        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);
            }
        }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
 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);
     }
 }
예제 #11
0
        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);
                }
            }
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
파일: ZDP.cs 프로젝트: wabberz/Kuriimu
        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);
                }
            }
        }
예제 #15
0
파일: ARCV.cs 프로젝트: 491467928/Kuriimu
        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);
            }
        }
예제 #16
0
파일: HPIHPB.cs 프로젝트: getov/Kuriimu
        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');
                    }
                }
        }
예제 #17
0
파일: MSBT.cs 프로젝트: getov/Kuriimu
        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);
        }
예제 #18
0
파일: STEX.cs 프로젝트: Moonstriker/Kuriimu
        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);
            }
        }
예제 #19
0
 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);
             }
         }
     }
 }
예제 #20
0
파일: GMM.cs 프로젝트: Moonstriker/Kuriimu
        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);
            }
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
파일: MSBT.cs 프로젝트: getov/Kuriimu
        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);
        }
예제 #23
0
파일: MSBT.cs 프로젝트: getov/Kuriimu
        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);
        }
예제 #24
0
파일: MSBT.cs 프로젝트: getov/Kuriimu
        // 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);
        }
예제 #25
0
파일: GAR.cs 프로젝트: benladen/Kuriimu
        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);
            }
        }
예제 #26
0
파일: CTPK.cs 프로젝트: wabberz/Kuriimu
        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));
                        }
                    }
                }
            }
        }
예제 #27
0
파일: GMD.cs 프로젝트: adibsurani/Kuriimu
        // 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);
        }
예제 #28
0
파일: CTPK.cs 프로젝트: Moonstriker/Kuriimu
        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);
                }
            }
        }
예제 #29
0
파일: Yaz0.cs 프로젝트: Moonstriker/Kuriimu
        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());
            }
        }
예제 #30
0
        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);
        }