Exemplo n.º 1
0
        /// <summary>
        /// Gets the <see cref="IFileFormat"/> from a file or byte array.
        /// </summary>
        /// <param name="FileName">The name of the file</param>
        /// <param name="data">The byte array of the data</param>
        /// <param name="InArchive">If the file is in an archive so it can be saved back</param>
        /// <param name="archiveNode">The node being replaced from an archive</param>
        /// <param name="Compressed">If the file is being compressed or not</param>
        /// <param name="CompType">The type of <see cref="CompressionType"/> being used</param>
        /// <returns></returns>
        public static IFileFormat OpenFileFormat(Stream stream, string FileName, byte[] data = null, bool LeaveStreamOpen = false, bool InArchive = false,
                                                 TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0, uint DecompressedSize = 0, uint CompressedSize = 0)
        {
            uint DecompressedFileSize = 0;
            uint CompressedFileSize   = 0;

            using (var fileReader = new FileReader(stream, true))
            {
                if (CompType == CompressionType.None)
                {
                    DecompressedFileSize = (uint)fileReader.BaseStream.Length;
                }
                if (CompType != CompressionType.None)
                {
                    CompressedFileSize = (uint)fileReader.BaseStream.Length;
                }

                if (fileReader.BaseStream.Length <= 4)
                {
                    fileReader.Close();
                    fileReader.Dispose();
                    return(null);
                }

                Cursor.Current       = Cursors.WaitCursor;
                fileReader.ByteOrder = ByteOrder.BigEndian;
                uint MagicHex = fileReader.ReadUInt32();

                string Magic = fileReader.ReadMagic(0, 4);

                fileReader.Position = 0;
                ushort MagicHex2 = fileReader.ReadUInt16();

                //Another hacky magic check if decomp size is first
                fileReader.Position = 4;
                ushort MagicHex3 = fileReader.ReadUInt16();

                //Note this method will soon be how all compression formats are handled rather than being checked here
                foreach (ICompressionFormat compressionFormat in FileManager.GetCompressionFormats())
                {
                    if (compressionFormat.Identify(stream))
                    {
                        stream = compressionFormat.Decompress(stream);
                    }
                }

                if (Magic == "Yaz0")
                {
                    if (data != null)
                    {
                        data = EveryFileExplorer.YAZ0.Decompress(data);
                    }
                    else
                    {
                        data = EveryFileExplorer.YAZ0.Decompress(FileName);
                    }

                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Yaz0, DecompressedFileSize, CompressedFileSize));
                }
                if (Path.GetExtension(FileName) == ".cbtex")
                {
                    fileReader.Position = 0;
                    byte compType = fileReader.ReadByte();
                    if (compType == 0x50)
                    {
                        if (data == null)
                        {
                            data = File.ReadAllBytes(FileName);
                        }

                        fileReader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;

                        fileReader.Seek(4, System.IO.SeekOrigin.Begin);
                        uint decompSize = fileReader.ReadUInt32();
                        uint compSize   = (uint)fileReader.BaseStream.Length - 8;

                        var comp = new STLibraryCompression.MTA_CUSTOM();
                        data = comp.Decompress(data, decompSize);

                        return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                              CompressionType.MarioTennisCustom, DecompressedFileSize, CompressedFileSize));
                    }
                    fileReader.Position = 0;
                }
                if (Path.GetExtension(FileName) == ".lz")
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    data = LZ77_WII.Decompress(fileReader.getSection(16, data.Length - 16));

                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Yaz0, DecompressedFileSize, CompressedFileSize));
                }
                if (MagicHex == 0x28B52FFD || MagicHex == 0xFD2FB528)
                {
                    if (data != null)
                    {
                        data = STLibraryCompression.ZSTD.Decompress(fileReader.getSection(0, data.Length));
                    }
                    else
                    {
                        data = STLibraryCompression.ZSTD.Decompress(File.ReadAllBytes(FileName));
                    }

                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Zstb, DecompressedFileSize, CompressedFileSize));
                }
                if (Magic == "ZCMP" || MagicHex2 == 0x789C || MagicHex2 == 0x78DA || Path.GetExtension(FileName) == ".z" && CompType == CompressionType.None)
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    data = STLibraryCompression.ZLIB.Decompress(data);
                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Zlib, DecompressedFileSize, CompressedFileSize));
                }
                if (MagicHex3 == 0x789C || MagicHex3 == 0x78DA && CompType == CompressionType.None)
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    fileReader.Position = 0;
                    int OuSize = fileReader.ReadInt32();
                    int InSize = data.Length - 4;
                    data = STLibraryCompression.ZLIB.Decompress(fileReader.getSection(4, InSize));
                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Zlib, DecompressedFileSize, CompressedFileSize));
                }
                if (Path.GetExtension(FileName) == ".carc" && CompType == CompressionType.None)
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    data = STLibraryCompression.ZLIB.Decompress(fileReader.getSection(0x10, data.Length - 0x10));
                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Zlib, DecompressedFileSize, CompressedFileSize));
                }
                if (Magic == "ZLIB")
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    data = STLibraryCompression.GZIP.Decompress(fileReader.getSection(64, data.Length - 64));
                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Zlib, DecompressedFileSize, CompressedFileSize));
                }
                if (MagicHex == 0x1f8b0808 || MagicHex2 == 0x1f8b && CompType == CompressionType.None)
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    data = STLibraryCompression.GZIP.Decompress(data);
                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Gzip, DecompressedFileSize, CompressedFileSize));
                }
                if (MagicHex == 0x184D2204)
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    data = STLibraryCompression.Type_LZ4.Decompress(data);
                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Lz4, DecompressedFileSize, CompressedFileSize));
                }
                if (Path.GetExtension(FileName) == ".lz" && CompType == CompressionType.None)
                {
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    data = STLibraryCompression.LZ77.Decompress(fileReader.getSection(16, data.Length - 16));
                    return(OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
                                          CompressionType.Zlib, DecompressedFileSize, CompressedFileSize));
                }
                if (Path.GetExtension(FileName) == ".cmp" && CompType == CompressionType.None)
                {
                    if (stream != null)
                    {
                        data = stream.ToArray();
                    }
                    if (data == null)
                    {
                        data = File.ReadAllBytes(FileName);
                    }

                    fileReader.Position = 0;
                    int OuSize = fileReader.ReadInt32();
                    int InSize = data.Length - 4;
                    data = STLibraryCompression.Type_LZ4F.Decompress(fileReader.getSection(4, InSize));

                    return(OpenFileFormat(FileName, data, InArchive, LeaveStreamOpen, archiveNode, true,
                                          CompressionType.Lz4f, DecompressedFileSize, CompressedFileSize));
                }
            }

            foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
            {
                //Set the file name so we can check it's extension in the identifier.
                //Most is by magic but some can be extension or name.

                fileFormat.FileName = Path.GetFileName(FileName);

                if (fileFormat.Identify(stream))
                {
                    fileFormat.IFileInfo = new IFileInfo();
                    fileFormat.IFileInfo.DecompressedSize = DecompressedFileSize;
                    fileFormat.IFileInfo.CompressedSize   = CompressedFileSize;
                    return(SetFileFormat(fileFormat, FileName, stream, LeaveStreamOpen, InArchive, archiveNode, Compressed, CompType));
                }
            }

            return(null);
        }