Exemplo n.º 1
0
        private static string DetectExtension(Stream input, Big.Entry entry)
        {
            var guess = new byte[64];
            int read  = 0;

            if (entry.CompressionScheme == Big.CompressionScheme.None)
            {
                if (entry.CompressedSize > 0)
                {
                    input.Seek(entry.Offset, SeekOrigin.Begin);
                    read = input.Read(guess, 0, (int)Math.Min(
                                          entry.CompressedSize, guess.Length));
                }
            }
            else if (entry.CompressionScheme == Big.CompressionScheme.LZO1x)
            {
                input.Seek(entry.Offset, SeekOrigin.Begin);

                var compressedData = new byte[entry.CompressedSize];
                if (input.Read(compressedData, 0, compressedData.Length) != compressedData.Length)
                {
                    throw new EndOfStreamException();
                }

                var  uncompressedData = new byte[entry.UncompressedSize];
                uint uncompressedSize = entry.UncompressedSize;

                var result = LZO1x.Decompress(
                    compressedData,
                    entry.CompressedSize,
                    uncompressedData,
                    ref uncompressedSize);
                if (result != 0)
                {
                    throw new InvalidOperationException("decompression error: " + result.ToString());
                }
                else if (uncompressedSize != entry.UncompressedSize)
                {
                    throw new InvalidOperationException("did not decompress correct amount of data");
                }

                Array.Copy(uncompressedData, 0, guess, 0, Math.Min(guess.Length, uncompressedData.Length));
                read = uncompressedData.Length;
            }
            else
            {
                throw new NotSupportedException();
            }

            return(FileExtensions.Detect(guess, Math.Min(guess.Length, read)));
        }
Exemplo n.º 2
0
        private static void ExtractFile(Stream input, Big.Entry entry, Stream output)
        {
            if (entry.CompressionScheme == Big.CompressionScheme.None)
            {
                if (entry.CompressedSize > 0)
                {
                    input.Seek(entry.Offset, SeekOrigin.Begin);
                    output.WriteFromStream(input, entry.CompressedSize);
                }
            }
            else if (entry.CompressionScheme == Big.CompressionScheme.LZO1x)
            {
                if (entry.UncompressedSize > 0)
                {
                    input.Seek(entry.Offset, SeekOrigin.Begin);

                    var compressedData = new byte[entry.CompressedSize];
                    if (input.Read(compressedData, 0, compressedData.Length) != compressedData.Length)
                    {
                        throw new EndOfStreamException();
                    }

                    var  uncompressedData = new byte[entry.UncompressedSize];
                    uint uncompressedSize = entry.UncompressedSize;

                    var result = LZO1x.Decompress(
                        compressedData,
                        entry.CompressedSize,
                        uncompressedData,
                        ref uncompressedSize);
                    if (result != 0)
                    {
                        throw new InvalidOperationException("decompression error: " + result.ToString());
                    }
                    else if (uncompressedSize != entry.UncompressedSize)
                    {
                        throw new InvalidOperationException("did not decompress correct amount of data");
                    }

                    output.Write(uncompressedData, 0, uncompressedData.Length);
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Exemplo n.º 3
0
        public static void Main(string[] args)
        {
            bool showHelp       = false;
            bool overwriteFiles = false;
            bool verbose        = false;

            var options = new OptionSet()
            {
                {
                    "v|verbose",
                    "be verbose",
                    v => verbose = v != null
                },
                {
                    "h|help",
                    "show this message and exit",
                    v => showHelp = v != null
                },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 || extras.Count > 2 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_fat [output_dir]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            string inputPath  = extras[0];
            string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null) + "_unpack";

            var manager = ProjectData.Manager.Load();

            if (manager.ActiveProject == null)
            {
                Console.WriteLine("Warning: no active project loaded.");
            }

            var hashes = manager.LoadLists(
                "*.filelist",
                s => s.HashFileNameCRC32(),
                s => s.ToLowerInvariant());

            var map = new MapFile();

            using (var input = File.OpenRead(inputPath))
            {
                map.Deserialize(input);
            }

            Directory.CreateDirectory(outputPath);
            using (var output = File.Create(Path.Combine(outputPath, "map.xml")))
            {
                var settings = new XmlWriterSettings();
                settings.Indent = true;

                using (var writer = XmlWriter.Create(output, settings))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("map");

                    writer.WriteStartElement("info");
                    writer.WriteElementString("name", map.Info.Name);
                    writer.WriteElementString("creator", map.Info.Creator);
                    writer.WriteElementString("author", map.Info.Author);
                    writer.WriteElementString("size", map.Info.Size.ToString());
                    writer.WriteElementString("players", map.Info.Players.ToString());
                    writer.WriteElementString("unknown2", map.Info.Unknown2.ToString());
                    writer.WriteElementString("unknown3", map.Info.Unknown3.ToString());
                    writer.WriteElementString("unknown4", map.Info.Unknown4.ToString());
                    writer.WriteElementString("unknown5", map.Info.Unknown5.ToString());
                    writer.WriteElementString("unknown7", map.Info.Unknown7.ToString());
                    writer.WriteElementString("unknown10", map.Info.Unknown10.ToString());
                    writer.WriteStartElement("unknown11");
                    writer.WriteBinHex(map.Info.Unknown11, 0, map.Info.Unknown11.Length);
                    writer.WriteEndElement();
                    writer.WriteStartElement("unknown12");
                    writer.WriteBinHex(map.Info.Unknown12, 0, map.Info.Unknown12.Length);
                    writer.WriteEndElement();
                    writer.WriteElementString("unknown15", map.Info.Unknown15.ToString());
                    writer.WriteEndElement();

                    writer.WriteStartElement("snapshot");
                    writer.WriteElementString("width", map.Snapshot.Width.ToString());
                    writer.WriteElementString("height", map.Snapshot.Height.ToString());
                    writer.WriteElementString("bpp", map.Snapshot.BytesPerPixel.ToString());
                    writer.WriteElementString("unknown4", map.Snapshot.Unknown4.ToString());
                    writer.WriteEndElement();

                    writer.WriteStartElement("data");
                    writer.WriteElementString("unknown1", map.Data.Unknown1);
                    writer.WriteEndElement();

                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                }
            }

            using (var input = map.Archive.XML.Unpack())
            {
                using (var output = File.Create(Path.Combine(outputPath, "archive.xml")))
                {
                    output.WriteFromStream(input, input.Length);
                }
            }

            using (var output = File.Create(Path.Combine(outputPath, "snapshot.bin")))
            {
                output.Write(map.Snapshot.Data, 0, map.Snapshot.Data.Length);
            }

            var big = new BigFile();

            using (var input = map.Archive.FAT.Unpack())
            {
                big.Deserialize(input);
            }

            var dataPath = Path.Combine(outputPath, "archive");

            Directory.CreateDirectory(dataPath);

            using (var input = map.Archive.DAT.Unpack())
            {
                long current = 0;
                long total   = big.Entries.Count;

                foreach (var entry in big.Entries)
                {
                    current++;

                    string name = hashes[entry.NameHash];
                    if (name == null)
                    {
                        string extension;

                        // detect type
                        {
                            var guess = new byte[64];
                            int read  = 0;

                            if (entry.CompressionScheme == CompressionScheme.None)
                            {
                                if (entry.CompressedSize > 0)
                                {
                                    input.Seek(entry.Offset, SeekOrigin.Begin);
                                    read = input.Read(guess, 0, (int)Math.Min(
                                                          entry.CompressedSize, guess.Length));
                                }
                            }
                            else if (entry.CompressionScheme == CompressionScheme.LZO1x)
                            {
                                input.Seek(entry.Offset, SeekOrigin.Begin);

                                var compressedData = new byte[entry.CompressedSize];
                                if (input.Read(compressedData, 0, compressedData.Length) != compressedData.Length)
                                {
                                    throw new EndOfStreamException();
                                }

                                var  uncompressedData = new byte[entry.UncompressedSize];
                                uint uncompressedSize = entry.UncompressedSize;

                                var result = LZO1x.Decompress(
                                    compressedData,
                                    entry.CompressedSize,
                                    uncompressedData,
                                    ref uncompressedSize);
                                if (result != 0)
                                {
                                    throw new InvalidOperationException("decompression error: " + result.ToString());
                                }
                                else if (uncompressedSize != entry.UncompressedSize)
                                {
                                    throw new InvalidOperationException("did not decompress correct amount of data");
                                }

                                Array.Copy(uncompressedData, 0, guess, 0, Math.Min(guess.Length, uncompressedData.Length));
                                read = uncompressedData.Length;
                            }
                            else
                            {
                                throw new NotSupportedException();
                            }

                            extension = FileExtensions.Detect(guess, Math.Min(guess.Length, read));
                        }

                        name = entry.NameHash.ToString("X8");
                        name = Path.ChangeExtension(name, "." + extension);
                        name = Path.Combine(extension, name);
                        name = Path.Combine("__UNKNOWN", name);
                    }
                    else
                    {
                        name = name.Replace("/", "\\");
                        if (name.StartsWith("\\") == true)
                        {
                            name = name.Substring(1);
                        }
                    }

                    var entryPath = Path.Combine(dataPath, name);
                    Directory.CreateDirectory(Path.GetDirectoryName(entryPath));

                    if (overwriteFiles == false &&
                        File.Exists(entryPath) == true)
                    {
                        continue;
                    }

                    if (verbose == true)
                    {
                        Console.WriteLine("[{0}/{1}] {2}",
                                          current, total, name);
                    }

                    using (var output = File.Create(entryPath))
                    {
                        if (entry.CompressionScheme == CompressionScheme.None)
                        {
                            if (entry.CompressedSize > 0)
                            {
                                input.Seek(entry.Offset, SeekOrigin.Begin);
                                output.WriteFromStream(input, entry.CompressedSize);
                            }
                        }
                        else if (entry.CompressionScheme == CompressionScheme.LZO1x)
                        {
                            if (entry.UncompressedSize > 0)
                            {
                                input.Seek(entry.Offset, SeekOrigin.Begin);

                                var compressedData = new byte[entry.CompressedSize];
                                if (input.Read(compressedData, 0, compressedData.Length) != compressedData.Length)
                                {
                                    throw new EndOfStreamException();
                                }

                                var  uncompressedData = new byte[entry.UncompressedSize];
                                uint uncompressedSize = entry.UncompressedSize;

                                var result = LZO1x.Decompress(
                                    compressedData,
                                    entry.CompressedSize,
                                    uncompressedData,
                                    ref uncompressedSize);
                                if (result != 0)
                                {
                                    throw new InvalidOperationException("decompression error: " + result.ToString());
                                }
                                else if (uncompressedSize != entry.UncompressedSize)
                                {
                                    throw new InvalidOperationException("did not decompress correct amount of data");
                                }

                                output.Write(uncompressedData, 0, uncompressedData.Length);
                            }
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        public static void Main(string[] args)
        {
            bool showHelp = false;
            bool verbose  = false;
            bool compress = false;

            var options = new OptionSet()
            {
                {
                    "v|verbose",
                    "be verbose",
                    v => verbose = v != null
                },
                {
                    "c|compress",
                    "compress data with LZO1x",
                    v => compress = v != null
                },
                {
                    "h|help",
                    "show this message and exit",
                    v => showHelp = v != null
                },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ output_fat input_directory+", GetExecutableName());
                Console.WriteLine("Pack files from input directories into a Encapsulated Resource File.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            var    inputPaths = new List <string>();
            string fatPath, datPath;

            if (extras.Count == 1)
            {
                inputPaths.Add(extras[0]);
                fatPath = Path.ChangeExtension(extras[0], ".fat");
                datPath = Path.ChangeExtension(extras[0], ".dat");
            }
            else
            {
                fatPath = extras[0];

                if (Path.GetExtension(fatPath) != ".fat")
                {
                    datPath = fatPath;
                    fatPath = Path.ChangeExtension(datPath, ".fat");
                }
                else
                {
                    datPath = Path.ChangeExtension(fatPath, ".dat");
                }

                inputPaths.AddRange(extras.Skip(1));
            }

            var paths = new SortedDictionary <uint, string>();

            if (verbose == true)
            {
                Console.WriteLine("Finding files...");
            }

            foreach (var relPath in inputPaths)
            {
                string inputPath = Path.GetFullPath(relPath);

                if (inputPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == true)
                {
                    inputPath = inputPath.Substring(0, inputPath.Length - 1);
                }

                foreach (string path in Directory.GetFiles(inputPath, "*", SearchOption.AllDirectories))
                {
                    string fullPath = Path.GetFullPath(path);
                    string partPath = fullPath.Substring(inputPath.Length + 1).ToLowerInvariant();

                    uint hash = 0xFFFFFFFFu;
                    if (partPath.ToUpper().StartsWith("__UNKNOWN") == true)
                    {
                        string partName;
                        partName = Path.GetFileNameWithoutExtension(partPath);
                        if (partName.Length > 8)
                        {
                            partName = partName.Substring(0, 8);
                        }

                        hash = uint.Parse(
                            partName,
                            System.Globalization.NumberStyles.AllowHexSpecifier);
                    }
                    else
                    {
                        hash = partPath.HashFileNameCRC32();
                    }

                    if (paths.ContainsKey(hash) == true)
                    {
                        //if (verbose == true)
                        {
                            Console.WriteLine("Ignoring {0} duplicate.", partPath);
                        }

                        continue;
                    }

                    paths[hash] = fullPath;
                    //Console.WriteLine(fullPath);
                }
            }

            var big = new BigFile();

            using (var output = File.Create(datPath))
            {
                foreach (var value in paths)
                {
                    var hash = value.Key;
                    var path = value.Value;

                    if (verbose == true)
                    {
                        Console.WriteLine(path);
                    }

                    var entry = new Big.Entry();
                    entry.NameHash = hash;
                    entry.Offset   = output.Position;

                    using (var input = File.OpenRead(path))
                    {
                        if (compress == false)
                        {
                            entry.CompressionScheme = Big.CompressionScheme.None;
                            entry.UncompressedSize  = 0;
                            entry.CompressedSize    = (uint)input.Length;
                            output.WriteFromStream(input, input.Length);
                        }
                        else
                        {
                            var uncompressedData = new byte[input.Length];
                            var uncompressedSize = (uint)uncompressedData.Length;
                            input.Read(uncompressedData, 0, uncompressedData.Length);

                            var compressedData = new byte[
                                uncompressedData.Length +
                                (uncompressedData.Length / 16) + 64 + 3];
                            var compressedSize = (uint)compressedData.Length;

                            var result = LZO1x.Compress(
                                uncompressedData, uncompressedSize,
                                compressedData, ref compressedSize);

                            if (result != 0)
                            {
                                throw new InvalidOperationException("compression error " + result.ToString());
                            }

                            if (compressedSize < uncompressedSize)
                            {
                                entry.CompressionScheme = Big.CompressionScheme.LZO1x;
                                entry.UncompressedSize  = uncompressedSize;
                                entry.CompressedSize    = compressedSize;
                                output.Write(compressedData, 0, (int)compressedSize);
                            }
                            else
                            {
                                input.Seek(0, SeekOrigin.Begin);
                                entry.CompressionScheme = Big.CompressionScheme.None;
                                entry.UncompressedSize  = 0;
                                entry.CompressedSize    = (uint)input.Length;
                                output.WriteFromStream(input, input.Length);
                            }
                        }

                        output.Seek(output.Position.Align(16), SeekOrigin.Begin);
                    }

                    big.Entries.Add(entry);
                }
            }

            using (var output = File.Create(fatPath))
            {
                big.Serialize(output);
            }
        }
Exemplo n.º 5
0
        public static void Main(string[] args)
        {
            bool showHelp        = false;
            bool extractUnknowns = true;
            bool noArt           = true;
            bool overwriteFiles  = false;
            bool verbose         = false;

            var options = new OptionSet()
            {
                {
                    "o|overwrite",
                    "overwrite existing files",
                    v => overwriteFiles = v != null
                },
                {
                    "na|no-art",
                    "don't extract art files (textures, models, etc)",
                    v => noArt = v != null
                },
                {
                    "nu|no-unknowns",
                    "don't extract unknown files",
                    v => extractUnknowns = v == null
                },
                {
                    "v|verbose",
                    "be verbose",
                    v => verbose = v != null
                },
                {
                    "h|help",
                    "show this message and exit",
                    v => showHelp = v != null
                },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 || extras.Count > 2 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_fat [output_dir]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            string fatPath    = extras[0];
            string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(fatPath, null) + "_unpack";
            string datPath;

            if (Path.GetExtension(fatPath) == ".dat")
            {
                datPath = fatPath;
                fatPath = Path.ChangeExtension(fatPath, ".fat");
            }
            else
            {
                datPath = Path.ChangeExtension(fatPath, ".dat");
            }

            var manager = ProjectData.Manager.Load();

            if (manager.ActiveProject == null)
            {
                Console.WriteLine("Warning: no active project loaded.");
            }

            var hashes = manager.LoadLists(
                "*.filelist",
                s => s.HashFileNameCRC32(),
                s => s.ToLowerInvariant());

            var big = new BigFile();

            using (var input = File.OpenRead(fatPath))
            {
                big.Deserialize(input);
            }

            using (var input = File.OpenRead(datPath))
            {
                long current = 0;
                long total   = big.Entries.Count;

                foreach (var entry in big.Entries)
                {
                    current++;

                    string name = hashes[entry.NameHash];
                    if (name == null)
                    {
                        if (extractUnknowns == false)
                        {
                            continue;
                        }

                        string extension;

                        // detect type
                        {
                            var guess = new byte[64];
                            int read  = 0;

                            if (entry.CompressionScheme == CompressionScheme.None)
                            {
                                if (entry.CompressedSize > 0)
                                {
                                    input.Seek(entry.Offset, SeekOrigin.Begin);
                                    read = input.Read(guess, 0, (int)Math.Min(
                                                          entry.CompressedSize, guess.Length));
                                }
                            }
                            else if (entry.CompressionScheme == CompressionScheme.LZO1x)
                            {
                                input.Seek(entry.Offset, SeekOrigin.Begin);

                                var compressedData = new byte[entry.CompressedSize];
                                if (input.Read(compressedData, 0, compressedData.Length) != compressedData.Length)
                                {
                                    throw new EndOfStreamException();
                                }

                                var  uncompressedData = new byte[entry.UncompressedSize];
                                uint uncompressedSize = entry.UncompressedSize;

                                var result = LZO1x.Decompress(
                                    compressedData,
                                    entry.CompressedSize,
                                    uncompressedData,
                                    ref uncompressedSize);
                                if (result != 0)
                                {
                                    throw new InvalidOperationException("decompression error: " + result.ToString());
                                }
                                else if (uncompressedSize != entry.UncompressedSize)
                                {
                                    throw new InvalidOperationException("did not decompress correct amount of data");
                                }

                                Array.Copy(uncompressedData, 0, guess, 0, Math.Min(guess.Length, uncompressedData.Length));
                                read = uncompressedData.Length;
                            }
                            else
                            {
                                throw new NotSupportedException();
                            }

                            extension = FileExtensions.Detect(guess, Math.Min(guess.Length, read));
                        }

                        name = entry.NameHash.ToString("X8");
                        name = Path.ChangeExtension(name, "." + extension);
                        name = Path.Combine(extension, name);
                        name = Path.Combine("__UNKNOWN", name);
                    }
                    else
                    {
                        name = name.Replace("/", "\\");
                        if (name.StartsWith("\\") == true)
                        {
                            name = name.Substring(1);
                        }
                    }

                    if (noArt == true)
                    {
                        var ext = Path.GetExtension(name);
                        if (ext == ".xbt" ||
                            ext == ".xbg" ||
                            ext == ".xbm" ||
                            ext == ".spk" ||
                            ext == ".mab" ||
                            ext == ".lfe" ||
                            ext == ".lfa" ||
                            ext == ".rtx" ||
                            ext == ".apm")
                        {
                            continue;
                        }
                    }

                    var entryPath = Path.Combine(outputPath, name);
                    Directory.CreateDirectory(Path.GetDirectoryName(entryPath));

                    if (overwriteFiles == false &&
                        File.Exists(entryPath) == true)
                    {
                        continue;
                    }

                    if (verbose == true)
                    {
                        Console.WriteLine("[{0}/{1}] {2}",
                                          current, total, name);
                    }

                    using (var output = File.Create(entryPath))
                    {
                        if (entry.CompressionScheme == CompressionScheme.None)
                        {
                            if (entry.CompressedSize > 0)
                            {
                                input.Seek(entry.Offset, SeekOrigin.Begin);
                                output.WriteFromStream(input, entry.CompressedSize);
                            }
                        }
                        else if (entry.CompressionScheme == CompressionScheme.LZO1x)
                        {
                            if (entry.UncompressedSize > 0)
                            {
                                input.Seek(entry.Offset, SeekOrigin.Begin);

                                var compressedData = new byte[entry.CompressedSize];
                                if (input.Read(compressedData, 0, compressedData.Length) != compressedData.Length)
                                {
                                    throw new EndOfStreamException();
                                }

                                var  uncompressedData = new byte[entry.UncompressedSize];
                                uint uncompressedSize = entry.UncompressedSize;

                                var result = LZO1x.Decompress(
                                    compressedData,
                                    entry.CompressedSize,
                                    uncompressedData,
                                    ref uncompressedSize);
                                if (result != 0)
                                {
                                    throw new InvalidOperationException("decompression error: " + result.ToString());
                                }
                                else if (uncompressedSize != entry.UncompressedSize)
                                {
                                    throw new InvalidOperationException("did not decompress correct amount of data");
                                }

                                output.Write(uncompressedData, 0, uncompressedData.Length);
                            }
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        private static bool UnpackFileFromBig(string fatPath, string fileName, string outputPath)
        {
            var datPath = Path.ChangeExtension(fatPath, ".dat");

            if (File.Exists(fatPath) == false ||
                File.Exists(datPath) == false)
            {
                return(false);
            }

            var big = new BigFile();

            using (var input = File.OpenRead(fatPath))
            {
                big.Deserialize(input);
            }

            var entries = big.Entries.Where(e => e.NameHash == fileName.HashFileNameCRC32());

            if (entries.Count() == 0)
            {
                return(false);
            }

            var entry = entries.First();

            using (var input = File.OpenRead(datPath))
            {
                using (var output = File.Create(outputPath))
                {
                    if (entry.CompressionScheme == Big.CompressionScheme.None)
                    {
                        if (entry.CompressedSize > 0)
                        {
                            input.Seek(entry.Offset, SeekOrigin.Begin);
                            output.WriteFromStream(input, entry.CompressedSize);
                        }
                    }
                    else if (entry.CompressionScheme == Big.CompressionScheme.LZO1x)
                    {
                        if (entry.UncompressedSize > 0)
                        {
                            input.Seek(entry.Offset, SeekOrigin.Begin);

                            var compressedData = new byte[entry.CompressedSize];
                            if (input.Read(compressedData, 0, compressedData.Length) != compressedData.Length)
                            {
                                throw new EndOfStreamException();
                            }

                            var  uncompressedData = new byte[entry.UncompressedSize];
                            uint uncompressedSize = entry.UncompressedSize;

                            var result = LZO1x.Decompress(
                                compressedData,
                                entry.CompressedSize,
                                uncompressedData,
                                ref uncompressedSize);
                            if (result != 0)
                            {
                                throw new InvalidOperationException("decompression error: " + result.ToString());
                            }
                            else if (uncompressedSize != entry.UncompressedSize)
                            {
                                throw new InvalidOperationException("did not decompress correct amount of data");
                            }

                            output.Write(uncompressedData, 0, uncompressedData.Length);
                        }
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }

            return(true);
        }