Пример #1
0
        public static void Pack(Stream inputStream, Stream outputStream, GcGame game)
        {
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }
            if (outputStream == null)
            {
                throw new ArgumentNullException("outputStream");
            }
            if (!Enum.IsDefined(typeof(GcGame), game))
            {
                throw new ArgumentOutOfRangeException("game");
            }

            // Read the input data and compress with LZSS
            byte[] uncompressedData = StreamUtil.ReadFully(inputStream);

            LzssEncoder encoder = new LzssEncoder();

            byte[] compressedData = encoder.Encode(uncompressedData);

            // Write file header and data
            int headerSizeField = compressedData.Length;

            if (LzVersionDetails.IsHeaderIncludedInCompressedSizeField(game))
            {
                headerSizeField += 8; // SMB1/SMB2 counts the 8 bytes of header in the compressed size field
            }
            EndianBinaryWriter outputBinaryWriter = new EndianBinaryWriter(EndianBitConverter.Little, outputStream);

            outputBinaryWriter.Write(headerSizeField);
            outputBinaryWriter.Write(uncompressedData.Length);
            outputBinaryWriter.Write(compressedData);
        }
Пример #2
0
        public static void Unpack(Stream inputStream, Stream outputStream, GcGame game)
        {
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }
            if (outputStream == null)
            {
                throw new ArgumentNullException("outputStream");
            }
            if (!Enum.IsDefined(typeof(GcGame), game))
            {
                throw new ArgumentOutOfRangeException("game");
            }

            EndianBinaryReader inputBinaryStream = new EndianBinaryReader(EndianBitConverter.Little, inputStream);

            // Read file header
            int headerSizeField  = inputBinaryStream.ReadInt32();
            int uncompressedSize = inputBinaryStream.ReadInt32();

            int compressedSize = headerSizeField;

            if (LzVersionDetails.IsHeaderIncludedInCompressedSizeField(game))
            {
                compressedSize -= 8; // SMB1/SMB2 counts the 8 bytes of header in the compressed size field
            }
            // Check that the size of the input matches the expected value
            if (compressedSize + 8 != inputStream.Length)
            {
                throw new InvalidLzFileException("Invalid .lz file, inputSize does not match actual input size.");
            }

            // Read and uncompress LZSS data
            byte[] compressedData = inputBinaryStream.ReadBytesOrThrow(compressedSize);

            LzssDecoder decoder = new LzssDecoder();

            byte[] uncompressedData = decoder.Decode(compressedData);
            if (uncompressedData.Length != uncompressedSize)
            {
                throw new InvalidLzFileException("Invalid .lz file, outputSize does not match actual output size.");
            }

            // Write uncompressed data to output stream
            outputStream.Write(uncompressedData, 0, uncompressedData.Length);
        }