Ejemplo n.º 1
0
        static void Test(byte[] bytes, Method method)
        {
            var bytes2 = new byte[bytes.Length];

            switch (method)
            {
            case Method.Ninty:
                bytes2 = Nintendo.Decompress(new MemoryStream(Nintendo.Compress(new MemoryStream(bytes), Nintendo.Method.LZ10)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Nintendo.Decompress(new MemoryStream(Nintendo.Compress(new MemoryStream(bytes), Nintendo.Method.LZ11)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Nintendo.Decompress(new MemoryStream(Nintendo.Compress(new MemoryStream(bytes), Nintendo.Method.Huff4)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Nintendo.Decompress(new MemoryStream(Nintendo.Compress(new MemoryStream(bytes), Nintendo.Method.Huff8)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Nintendo.Decompress(new MemoryStream(Nintendo.Compress(new MemoryStream(bytes), Nintendo.Method.RLE)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                break;

            case Method.L5:
                bytes2 = Level5.Decompress(new MemoryStream(Level5.Compress(new MemoryStream(bytes), Level5.Method.NoCompression)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Level5.Decompress(new MemoryStream(Level5.Compress(new MemoryStream(bytes), Level5.Method.LZ10)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Level5.Decompress(new MemoryStream(Level5.Compress(new MemoryStream(bytes), Level5.Method.Huffman4Bit)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Level5.Decompress(new MemoryStream(Level5.Compress(new MemoryStream(bytes), Level5.Method.Huffman8Bit)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                bytes2 = Level5.Decompress(new MemoryStream(Level5.Compress(new MemoryStream(bytes), Level5.Method.RLE)));
                Assert.IsTrue(bytes.SequenceEqual(bytes2));
                break;
            }
        }
Ejemplo n.º 2
0
        private byte[] CompressTable <T>(List <T> table, Level5.Method method)
        {
            var ms = new MemoryStream();

            using (var bw = new BinaryWriterX(ms, true))
                bw.WriteMultiple(table);
            ms.Position = 0;
            return(Level5.Compress(ms, method));
        }
Ejemplo n.º 3
0
        public void Save(string filename)
        {
            //Save available after finding out the comp table Size or if changes work without this comp table Size
            var sjis = Encoding.GetEncoding("SJIS");

            using (BinaryWriterX bw = new BinaryWriterX(File.OpenWrite(filename)))
            {
                //Header
                bw.WriteStruct(header);

                //Table 1
                bw.Write(table1);

                //Table2
                uint relOffset = 0;
                var  count     = 1;
                foreach (var label in Labels)
                {
                    if (count == offsets.Count)
                    {
                        var byteCount = (uint)sjis.GetByteCount(label.Text) + 1;

                        foreach (var entry in entries)
                        {
                            if (entry.ident == 0x18 && entry.textOffset == offsets[count])
                            {
                                entry.textOffset = relOffset + byteCount;
                            }
                        }

                        relOffset += byteCount;
                        count++;
                    }
                }

                var ms = new MemoryStream();
                using (var bw2 = new BinaryWriterX(ms, true))
                    foreach (var entry in entries)
                    {
                        bw2.WriteStruct(entry);
                    }
                bw.Write(Level5.Compress(ms, Level5.Method.NoCompression));
                bw.BaseStream.Position = (bw.BaseStream.Position + 0x3) & ~0x3;

                //Text
                ms = new MemoryStream();
                using (var bw2 = new BinaryWriterX(ms, true))
                    foreach (var label in Labels)
                    {
                        bw2.Write(sjis.GetBytes(label.Text));
                        bw2.Write((byte)0);
                    }
                bw.Write(Level5.Compress(ms, Level5.Method.NoCompression));
            }
        }
Ejemplo n.º 4
0
        public static void WriteMultipleCompressed <T>(this BinaryWriterX bw, IEnumerable <T> list, Level5.Method comp)
        {
            var ms = new MemoryStream();

            using (var bwIntern = new BinaryWriterX(ms, true))
                foreach (var t in list)
                {
                    bwIntern.WriteStruct(t);
                }
            bw.Write(Level5.Compress(ms, comp));
        }
Ejemplo n.º 5
0
        public static void WriteStringsCompressed(this BinaryWriterX bw, IEnumerable <string> list, Level5.Method comp, Encoding enc)
        {
            var ms = new MemoryStream();

            using (var bwIntern = new BinaryWriterX(ms, true))
                foreach (var t in list)
                {
                    bwIntern.Write(enc.GetBytes(t));
                    bwIntern.Write((byte)0);
                }
            bw.Write(Level5.Compress(ms, comp));
        }
Ejemplo n.º 6
0
        public static void Save(string filename, Bitmap bitmap)
        {
            int width  = (bitmap.Width + 0x7) & ~0x7;
            int height = (bitmap.Height + 0x7) & ~0x7;

            var settings = new ImageSettings
            {
                Width         = width,
                Height        = height,
                Orientation   = Orientation.TransposeTile,
                Format        = ImageSettings.ConvertFormat(header.imageFormat),
                PadToPowerOf2 = false
            };

            byte[] pic = Common.Save(bitmap, settings);

            using (var bw = new BinaryWriterX(File.Create(filename)))
            {
                //Header
                header.width  = (short)bitmap.Width;
                header.height = (short)bitmap.Height;

                //tile table
                var    table     = new MemoryStream();
                byte[] importPic = Deflate(pic, ImageSettings.ConvertFormat(header.imageFormat), out table);

                //Table
                bw.BaseStream.Position = 0x48;
                var comp = Level5.Compress(table, tableComp);
                bw.Write(comp);
                header.tableSize1 = comp.Length + 4;
                header.tableSize2 = (header.tableSize1 + 3) & ~3;

                //Image
                bw.BaseStream.Position = 0x48 + header.tableSize2;
                header.imageFormat     = (editMode) ? Format.ETC1 : header.imageFormat;
                comp = Level5.Compress(new MemoryStream(importPic), picComp);
                bw.Write(comp);
                header.imgDataSize = comp.Length;

                //Header
                bw.BaseStream.Position = 0;
                bw.WriteStruct(header);
            }
        }
Ejemplo n.º 7
0
        public void Save(Stream file)
        {
            int width    = (Image.Width + 0x7) & ~0x7;
            int height   = (Image.Height + 0x7) & ~0x7;
            var settings = new ImageSettings
            {
                Width   = width,
                Height  = height,
                Format  = Support.Format[header.imageFormat],
                Swizzle = new ImgcSwizzle(width, height)
            };

            byte[] pic = L5XFEditor.Image.Common.Save(Image, settings);

            using (var bw = new BinaryWriterX(file, true))
            {
                //Header
                header.width  = (short)Image.Width;
                header.height = (short)Image.Height;

                //tile table
                var    table     = new MemoryStream();
                byte[] importPic = Deflate(pic, Support.Format[header.imageFormat].BitDepth, out table);

                //Table
                bw.BaseStream.Position = 0x48;
                var comp = Level5.Compress(table, tableComp);
                bw.Write(comp);
                header.tableSize1 = comp.Length;
                header.tableSize2 = (header.tableSize1 + 3) & ~3;

                //Image
                bw.BaseStream.Position = 0x48 + header.tableSize2;
                header.imageFormat     = (editMode) ? (byte)28 : header.imageFormat;
                comp = Level5.Compress(new MemoryStream(importPic), picComp);
                bw.Write(comp);
                bw.WriteAlignment(4);
                header.imgDataSize = comp.Length;

                //Header
                bw.BaseStream.Position = 0;
                bw.WriteStruct(header);
            }
        }
Ejemplo n.º 8
0
        public void Save(string filename)
        {
            int width              = (Image.Width + 0x7) & ~0x7;
            int height             = (Image.Height + 0x7) & ~0x7;
            var isBlockCompression = Support.Format[header.imageFormat].FormatName.Contains("DXT");
            var settings           = new ImageSettings
            {
                Width   = width,
                Height  = height,
                Format  = Support.Format[header.imageFormat],
                Swizzle = isBlockCompression ? new Support.BlockSwizzle(header.width, header.height) : null
            };

            byte[] pic = Kontract.Image.Common.Save(Image, settings);

            using (var bw = new BinaryWriterX(File.Create(filename)))
            {
                //Header
                header.width  = (short)Image.Width;
                header.height = (short)Image.Height;

                //tile table
                var    table     = new MemoryStream();
                byte[] importPic = Deflate(pic, Support.Format[header.imageFormat].BitDepth, out table);

                //Table
                bw.BaseStream.Position = 0x48;
                var comp = Level5.Compress(table, tableComp);
                bw.Write(comp);
                header.tableSize1 = comp.Length;
                header.tableSize2 = (header.tableSize1 + 3) & ~3;

                //Image
                bw.BaseStream.Position = 0x48 + header.tableSize2;
                comp = Level5.Compress(new MemoryStream(importPic), picComp);
                bw.Write(comp);
                bw.WriteAlignment(4);
                header.imgDataSize = comp.Length;

                //Header
                bw.BaseStream.Position = 0;
                bw.WriteStruct(header);
            }
        }
Ejemplo n.º 9
0
        public static void Compress(object sender, EventArgs e)
        {
            var tsi = sender as ToolStripMenuItem;

            if (!Shared.PrepareFiles("Open a decompressed " + tsi?.Tag + "file...", "Save your compressed file...", ".decomp", out var openFile, out var saveFile, true))
            {
                return;
            }

            try
            {
                using (openFile)
                    using (var outFs = new BinaryWriterX(saveFile))
                        switch (tsi?.Tag)
                        {
                        case Compression.L5LZ10:
                            outFs.Write(Level5.Compress(openFile, Level5.Method.LZ10));
                            break;

                        case Compression.L5Huff4:
                            outFs.Write(Level5.Compress(openFile, Level5.Method.Huffman4Bit));
                            break;

                        case Compression.L5Huff8:
                            outFs.Write(Level5.Compress(openFile, Level5.Method.Huffman8Bit));
                            break;

                        case Compression.L5RLE:
                            outFs.Write(Level5.Compress(openFile, Level5.Method.RLE));
                            break;

                        case Compression.NLZ10:
                            outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ10));
                            break;

                        case Compression.NLZ11:
                            outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ11));
                            break;

                        case Compression.NLZ60:
                            outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ60));
                            break;

                        case Compression.NHuff4:
                            outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.Huff4));
                            break;

                        case Compression.NHuff8:
                            outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.Huff8));
                            break;

                        case Compression.NRLE:
                            outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.RLE));
                            break;

                        case Compression.LZ77:
                            outFs.Write(LZ77.Compress(openFile));
                            break;

                        case Compression.RevLZ77:
                            outFs.Write(RevLZ77.Compress(openFile));
                            break;

                        case Compression.LZOvl:
                            outFs.Write(LZOvl.Compress(openFile));
                            break;

                        case Compression.LZ4:
                            outFs.Write(Kontract.Compression.LZ4.Compress(openFile));
                            break;

                        case Compression.MIO0LE:
                            outFs.Write(MIO0.Compress(openFile, ByteOrder.LittleEndian));
                            break;

                        case Compression.MIO0BE:
                            outFs.Write(MIO0.Compress(openFile, ByteOrder.BigEndian));
                            break;

                        case Compression.Yay0LE:
                            outFs.Write(Yay0.Compress(openFile, ByteOrder.LittleEndian));
                            break;

                        case Compression.Yay0BE:
                            outFs.Write(Yay0.Compress(openFile, ByteOrder.BigEndian));
                            break;

                        case Compression.Yaz0LE:
                            outFs.Write(Yaz0.Compress(openFile, ByteOrder.LittleEndian));
                            break;

                        case Compression.Yaz0BE:
                            outFs.Write(Yaz0.Compress(openFile, ByteOrder.BigEndian));
                            break;

                        case Compression.GZip:
                            outFs.Write(GZip.Compress(openFile));
                            break;

                        case Compression.ZLib:
                            outFs.Write(ZLib.Compress(openFile));
                            break;

                        case Compression.PSVSpikeChun:
                            outFs.Write(PSVSpikeChun.Compress(openFile));
                            break;
                        }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            MessageBox.Show($"Successfully compressed {Path.GetFileName(openFile.Name)}.", tsi.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
Ejemplo n.º 10
0
        public void Save(Stream xfsa)
        {
            //Table 1
            var ms = new MemoryStream();

            new BinaryWriterX(ms, true).WriteMultiple(table1);
            ms.Position = 0;
            var newTable1 = Level5.Compress(ms, (Level5.Method)table1Comp);

            //Table 2
            ms = new MemoryStream();
            new BinaryWriterX(ms, true).WriteMultiple(table2);
            ms.Position = 0;
            var newTable2 = Level5.Compress(ms, (Level5.Method)table2Comp);

            //Update Entries
            Files = Files.OrderBy(f => f.entry.entry.comb1 & 0x01ffffff).ToList();
            int offset = 0;

            foreach (var file in Files)
            {
                offset = file.UpdateEntry(offset);
            }

            //Get compressed Entry section
            Files = Files.OrderBy(f => f.entry.ID).ToList();
            ms    = new MemoryStream();
            new BinaryWriterX(ms, true).WriteMultiple(Files.Select(f => f.entry.entry));
            ms.Position = 0;
            var newEntryTable = Level5.Compress(ms, (Level5.Method)entriesComp);

            //Update header
            header.nameTableOffset = (uint)(0x24 + ((newTable1.Length + 3) & ~3) + ((newTable2.Length + 3) & ~3) + ((newEntryTable.Length + 3) & ~3));
            header.dataOffset      = (uint)(((header.nameTableOffset + nameC.Length) + 0xf) & ~0xf);

            using (BinaryWriterX bw = new BinaryWriterX(xfsa))
            {
                //Header
                bw.WriteStruct(header);

                //Table 1
                bw.Write(newTable1);
                bw.WriteAlignment(4);

                //Table 2
                bw.Write(newTable2);
                bw.WriteAlignment(4);

                //Entries
                bw.Write(newEntryTable);
                bw.WriteAlignment(4);

                //Names
                bw.Write(nameC);
                bw.WriteAlignment();

                //Files
                Files = Files.OrderBy(f => f.entry.entry.comb1 & 0x01ffffff).ToList();
                foreach (var file in Files)
                {
                    file.FileData.CopyTo(bw.BaseStream);
                    if (bw.BaseStream.Position % 0x10 != 0)
                    {
                        bw.WriteAlignment();
                    }
                    else
                    {
                        bw.Write(new byte[0x10]);
                    }
                }


                //FileEntries Table
                //bw.Write((entries.Count * 0xc) << 3);

                /*uint offset = 0;
                 * List<XFSAFileInfo> files = new List<XFSAFileInfo>();
                 * foreach (var entry in entries)
                 * {
                 *  var file = Files.Find(c => c.entry.comb1 == entry.comb1);
                 *  files.Add(file);
                 *
                 *  //catch file limits
                 *  if (file.FileData.Length >= 0x100000)
                 *  {
                 *      throw new Exception("File " + file.FileName + " is too big to pack into this archive type!");
                 *  }
                 *  else if (offset + dataOffset >= 0x20000000)
                 *  {
                 *      throw new Exception("The archive can't be bigger than 0x10000000 Bytes.");
                 *  }
                 *
                 *  //edit entry
                 *  entry.comb1 = (entry.comb1 & 0xfe000000) | (offset >> 4);
                 *  entry.comb2 = (entry.comb1 & 0xfff00000) | ((uint)file.FileData.Length);
                 *
                 *  //write entry
                 *  bw.WriteStruct(entry);
                 *
                 *  //edit values
                 *  offset = (uint)(((offset + file.FileData.Length) + 0xf) & ~0xf);
                 * }*/

                //Nametable
                //bw.Write(nameC);

                //Files
                //bw.BaseStream.Position = dataOffset;
                //foreach (var file in files)
                //{
                //    file.FileData.CopyTo(bw.BaseStream);
                //    bw.BaseStream.Position = (bw.BaseStream.Position + 0xf) & ~0xf;
                //}

                //Header
                //header.nameTableOffset = (uint)(0x24 + table1.Length + table2.Length + entries.Count * 0xc + 4);
                //header.dataOffset = (uint)dataOffset;
                //bw.BaseStream.Position = 0;
                //bw.WriteStruct(header);
            }
        }
Ejemplo n.º 11
0
        public void Save(Stream file)
        {
            using (var fw = new ImprovedBinaryWriter(file))
            {
                var   outstream   = new MemoryStream();
                short header_size = 0x20;

                var new_header = new Header
                {
                    Magic = header.Magic,
                    Unk1  = header.Unk1
                };

                byte[] data;

                using (var bw = new ImprovedBinaryWriter(outstream))
                {
                    // table 0
                    using (var table0 = new ImprovedBinaryWriter(new MemoryStream()))
                    {
                        new_header.T0       = (short)(header_size >> 2);
                        new_header.T0_Count = (short)t0_list.Count;

                        foreach (var entry in t0_list)
                        {
                            table0.WriteStruct(entry);
                        }

                        table0.BaseStream.Position = 0;
                        bw.Write(Level5.Compress(table0.BaseStream, Level5.Method.LZ10));
                        bw.WriteAlignment(4);
                    }

                    // table 1
                    using (var table1 = new ImprovedBinaryWriter(new MemoryStream()))
                    {
                        new_header.T1       = (short)((bw.BaseStream.Position + header_size) >> 2);
                        new_header.T1_Count = (short)t1_list.Count;

                        foreach (var entry in t1_list)
                        {
                            table1.WriteStruct(entry);
                        }

                        table1.BaseStream.Position = 0;
                        bw.Write(Level5.Compress(table1.BaseStream, Level5.Method.LZ10));
                        bw.WriteAlignment(4);
                    }

                    // table 2
                    using (var table2 = new ImprovedBinaryWriter(new MemoryStream()))
                    {
                        new_header.T2       = (short)((bw.BaseStream.Position + header_size) >> 2);
                        new_header.T2_Count = (short)t2_list.Count;

                        foreach (var entry in t2_list)
                        {
                            table2.WriteStruct(entry);
                        }

                        table2.BaseStream.Position = 0;
                        bw.Write(Level5.Compress(table2.BaseStream, Level5.Method.LZ10));
                        bw.WriteAlignment(4);
                    }

                    // table 3
                    using (var table3 = new ImprovedBinaryWriter(new MemoryStream()))
                    {
                        new_header.T3       = (short)((bw.BaseStream.Position + header_size) >> 2);
                        new_header.T3_Count = (short)t3_list.Count;

                        foreach (var entry in t3_list)
                        {
                            table3.WriteStruct(entry);
                        }

                        table3.BaseStream.Position = 0;
                        bw.Write(Level5.Compress(table3.BaseStream, Level5.Method.LZ10));
                        bw.WriteAlignment(4);
                    }

                    // table 4 (string data)
                    using (var table4 = new ImprovedBinaryWriter(new MemoryStream()))
                    {
                        new_header.T4 = (short)((bw.BaseStream.Position + header_size) >> 2);

                        table4.Write(t4_data.ToArray());

                        table4.BaseStream.Position = 0;
                        bw.Write(Level5.Compress(table4.BaseStream, Level5.Method.LZ10));
                        bw.WriteAlignment(4);
                    }

                    data = outstream.ToArray();
                }

                fw.WriteStruct(new_header);
                fw.WritePadding(8);

                fw.Write(data);
            }
        }
Ejemplo n.º 12
0
        public static void Compress(object sender, EventArgs e)
        {
            var tsi = sender as ToolStripMenuItem;

            if (!PrepareFiles("Open a decompressed " + tsi.Tag.ToString() + "file...", "Save your compressed file...", ".comp", out FileStream openFile, out FileStream saveFile))
            {
                return;
            }

            try
            {
                using (openFile)
                    using (var outFs = new BinaryWriterX(saveFile))
                        switch (tsi.Tag)
                        {
                        case Compression.Level5:
                            outFs.Write(Level5.Compress(openFile, Level5.Method.NoCompression));
                            break;

                        /*case Compression.L5LZSS:
                         *  outFs.Write(Level5.Compress(openFile, 1));
                         *  break;
                         * case Compression.L5Huff4:
                         *  outFs.Write(Level5.Compress(openFile, 2));
                         *  break;
                         * case Compression.L5Huff8:
                         *  outFs.Write(Level5.Compress(openFile, 3));
                         *  break;
                         * case Compression.L5RLE:
                         *  outFs.Write(Level5.Compress(openFile, 4));
                         *  break;*/
                        case Compression.GZip:
                            outFs.Write(GZip.Compress(openFile));
                            break;

                        case Compression.Huff4:
                            outFs.Write(Huffman.Compress(openFile, 4));
                            break;

                        case Compression.Huff8:
                            outFs.Write(Huffman.Compress(openFile, 8));
                            break;

                        case Compression.LZ10:
                            outFs.Write(LZ10.Compress(openFile));
                            break;

                        case Compression.LZ11:
                            outFs.Write(LZ11.Compress(openFile));
                            break;

                        /*case Compression.LZSS:
                         *  outFs.Write(LZSS.Compress(openFile));
                         *  break;*/
                        case Compression.RevLZ77:
                            outFs.Write(RevLZ77.Compress(openFile));
                            break;

                        case Compression.RLE:
                            outFs.Write(RLE.Compress(openFile));
                            break;

                        case Compression.ZLib:
                            outFs.Write(ZLib.Compress(openFile));
                            break;
                        }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            MessageBox.Show($"Successfully compressed {Path.GetFileName(openFile.Name)}.", tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
Ejemplo n.º 13
0
        public void Save(Stream xfsa)
        {
            //Update FileInfo
            int offset = 0;

            foreach (var file in Files)
            {
                entries[file.dirEntry.fileEntryOffset + file.fileCountInDir].offset = offset >> 4;
                file.fileEntry.offset = offset >> 4;

                entries[file.dirEntry.fileEntryOffset + file.fileCountInDir].size = (int)file.FileSize;
                file.fileEntry.size = (int)file.FileSize;

                var newOffset = ((offset + file.FileSize) % 16 == 0) ? offset + file.FileSize + 16 : (offset + file.FileSize + 0xf) & ~0xf;
                offset = (int)newOffset;
            }

            using (var bw = new BinaryWriterX(xfsa))
            {
                //Table 0
                bw.BaseStream.Position  = 0x24;
                header.table0Offset     = (int)bw.BaseStream.Position;
                header.table0EntryCount = (short)table0.Count;
                bw.Write(CompressTable(table0, table0Comp));

                //Table 1
                bw.BaseStream.Position  = (bw.BaseStream.Position + 3) & ~3;
                header.table1Offset     = (int)bw.BaseStream.Position;
                header.table1EntryCount = (short)table1.Count;
                bw.Write(CompressTable(table1, table1Comp));

                //FileEntries
                bw.BaseStream.Position      = (bw.BaseStream.Position + 3) & ~3;
                header.fileEntryTableOffset = (int)bw.BaseStream.Position;
                header.fileEntryCount       = entries.Count;
                bw.Write(CompressTable(entries, entriesComp));

                //StringTable
                bw.BaseStream.Position = (bw.BaseStream.Position + 3) & ~3;
                header.nameTableOffset = (int)bw.BaseStream.Position;
                bw.Write(Level5.Compress(new MemoryStream(stringTable), stringComp));

                //FileData
                bw.BaseStream.Position = (bw.BaseStream.Position + 0xf) & ~0xf;
                header.dataOffset      = (int)bw.BaseStream.Position;
                foreach (var file in Files)
                {
                    bw.BaseStream.Position = header.dataOffset + (file.fileEntry.offset << 4);
                    file.FileData.CopyTo(bw.BaseStream);
                    if (bw.BaseStream.Position % 16 == 0)
                    {
                        bw.WritePadding(16);
                    }
                    else
                    {
                        bw.WriteAlignment(16);
                    }
                }

                //Header
                bw.BaseStream.Position = 0;
                bw.WriteStruct(header);
            }

            //Table 1

            /*var ms = new MemoryStream();
             * new BinaryWriterX(ms, true).WriteMultiple(table0);
             * ms.Position = 0;
             * var newTable1 = Level5.Compress(ms, (Level5.Method)table1Comp);
             *
             * //Table 2
             * ms = new MemoryStream();
             * new BinaryWriterX(ms, true).WriteMultiple(table1);
             * ms.Position = 0;
             * var newTable2 = Level5.Compress(ms, (Level5.Method)table2Comp);
             *
             * //Update Entries
             * Files = Files.OrderBy(f => f.entry.entry.comb1 & 0x01ffffff).ToList();
             * int offset = 0;
             * foreach (var file in Files) offset = file.UpdateEntry(offset);
             *
             * //Get compressed Entry section
             * Files = Files.OrderBy(f => f.entry.ID).ToList();
             * ms = new MemoryStream();
             * new BinaryWriterX(ms, true).WriteMultiple(Files.Select(f => f.entry.entry));
             * ms.Position = 0;
             * var newEntryTable = Level5.Compress(ms, (Level5.Method)entriesComp);
             *
             * //Update header
             * header.nameTableOffset = (uint)(0x24 + ((newTable1.Length + 3) & ~3) + ((newTable2.Length + 3) & ~3) + ((newEntryTable.Length + 3) & ~3));
             * header.dataOffset = (uint)(((header.nameTableOffset + nameC.Length) + 0xf) & ~0xf);
             *
             * using (BinaryWriterX bw = new BinaryWriterX(xfsa))
             * {
             *  //Header
             *  bw.WriteStruct(header);
             *
             *  //Table 1
             *  bw.Write(newTable1);
             *  bw.WriteAlignment(4);
             *
             *  //Table 2
             *  bw.Write(newTable2);
             *  bw.WriteAlignment(4);
             *
             *  //Entries
             *  bw.Write(newEntryTable);
             *  bw.WriteAlignment(4);
             *
             *  //Names
             *  bw.Write(nameC);
             *  bw.WriteAlignment();
             *
             *  //Files
             *  Files = Files.OrderBy(f => f.entry.entry.comb1 & 0x01ffffff).ToList();
             *  foreach (var file in Files)
             *  {
             *      file.FileData.CopyTo(bw.BaseStream);
             *      if (bw.BaseStream.Position % 0x10 != 0)
             *          bw.WriteAlignment();
             *      else
             *      {
             *          bw.Write(new byte[0x10]);
             *      }
             *  }
             *
             *
             *  //FileEntries Table
             *  //bw.Write((entries.Count * 0xc) << 3);
             *
             *  /*uint offset = 0;
             *  List<XFSAFileInfo> files = new List<XFSAFileInfo>();
             *  foreach (var entry in entries)
             *  {
             *      var file = Files.Find(c => c.entry.comb1 == entry.comb1);
             *      files.Add(file);
             *
             *      //catch file limits
             *      if (file.FileData.Length >= 0x100000)
             *      {
             *          throw new Exception("File " + file.FileName + " is too big to pack into this archive type!");
             *      }
             *      else if (offset + dataOffset >= 0x20000000)
             *      {
             *          throw new Exception("The archive can't be bigger than 0x10000000 Bytes.");
             *      }
             *
             *      //edit entry
             *      entry.comb1 = (entry.comb1 & 0xfe000000) | (offset >> 4);
             *      entry.comb2 = (entry.comb1 & 0xfff00000) | ((uint)file.FileData.Length);
             *
             *      //write entry
             *      bw.WriteStruct(entry);
             *
             *      //edit values
             *      offset = (uint)(((offset + file.FileData.Length) + 0xf) & ~0xf);
             *  }*/

            //Nametable
            //bw.Write(nameC);

            //Files
            //bw.BaseStream.Position = dataOffset;
            //foreach (var file in files)
            //{
            //    file.FileData.CopyTo(bw.BaseStream);
            //    bw.BaseStream.Position = (bw.BaseStream.Position + 0xf) & ~0xf;
            //}

            //Header
            //header.nameTableOffset = (uint)(0x24 + table1.Length + table2.Length + entries.Count * 0xc + 4);
            //header.dataOffset = (uint)dataOffset;
            //bw.BaseStream.Position = 0;
            //bw.WriteStruct(header);
            //}
        }