public DecompressionParameters GetDecompressionParameters()
        {
            DecompressionParameters result = new DecompressionParameters
            {
                DictionarySize = DictionarySize,
                UpdateRate = UpdateRate,
            };

            result.Flags |= Zlib ? DecompressionFlag.ReadZlibStream : 0;
            result.Flags |= Unbuffered ? DecompressionFlag.OutputUnbuffered : 0;
            result.Flags |= NoAdler ? 0 : DecompressionFlag.ComputeAdler32;
            return result;
        }
Example #2
0
 public LzhamStream(Stream stream, DecompressionParameters mode, bool leaveOpen)
 {
     if (stream == null)
         throw new ArgumentNullException(nameof(stream));
     if (!stream.CanRead)
         throw new ArgumentException("The base stream is not readable", nameof(stream));
     _stream = stream;
     _leaveOpen = leaveOpen;
     _buffer = new byte[DefaultBufferSize];
     _decompressionHandle = LzhamInterop.DecompressInit(mode);
     if (_decompressionHandle.IsInvalid)
     {
         throw new ApplicationException("Could not initialize Decompression stream with specified parameters");
     }
     ReadInput();
 }
Example #3
0
 public LzhamStream(Stream stream, DecompressionParameters mode) : this(stream, mode, false)
 {
 }
Example #4
0
        private static int Unpack(UnpackOptions options)
        {
            string inputFile = options.InputFile;
            string outputFolder = options.OutputFolder ?? Environment.CurrentDirectory;
            using (FileStream fs = File.OpenRead(inputFile))
            using (BinaryReader br = new BinaryReader(fs))
            {
                int headerSize = Marshal.SizeOf(typeof(TimHeader));
                TimHeader header = Util.ByteArrayToStructure<TimHeader>(br.ReadBytes(headerSize));

                int exitCode = ValidateHeader(header);
                if (exitCode != 0)
                {
                    return exitCode;
                }

                fs.Seek((long)header.directoryListingOffset, SeekOrigin.Begin);
                byte[] directoryListingCompressed = br.ReadBytes((int)header.directoryListingCompressedSize);

                DecompressionParameters p = new DecompressionParameters
                {
                    DictionarySize = Util.GetDictLength(header.directoryListngSize),
                    UpdateRate = TableUpdateRate.Fastest
                };

                byte[] directoryListing = new byte[header.directoryListngSize];
                uint addler = 0;
                int outsize = (int)header.directoryListngSize;
                DecompressStatus status = Lzham.DecompressMemory(p, directoryListingCompressed, directoryListingCompressed.Length, 0, directoryListing, ref outsize, 0, ref addler);

                if (status != DecompressStatus.Success)
                {
                    Console.WriteLine("Failed to unpack directory listing");
                    return 5;
                }
                MD5 md5 = MD5.Create();
                byte[] directoryListingHash = md5.ComputeHash(directoryListing);
                if (!StructuralComparisons.StructuralEqualityComparer.Equals(directoryListingHash,header.directoryListingDigest))
                {
                    Console.WriteLine("Directory listing hash mismatch");
                    return 7;
                }

                fs.Seek((long)header.fileRegistryOffset, SeekOrigin.Begin);
                byte[] fileRegistryCompressed = br.ReadBytes((int)header.fileRegistryCompressedSize);

                outsize = (int)header.fileCount * Marshal.SizeOf(typeof(FileRegistryEntry));
                p = new DecompressionParameters
                {
                    DictionarySize = Util.GetDictLength((uint)outsize),
                    UpdateRate = TableUpdateRate.Fastest
                };
                byte[] fileRegistry = new byte[outsize];
                status = Lzham.DecompressMemory(p, fileRegistryCompressed, fileRegistryCompressed.Length, 0, fileRegistry, ref outsize, 0, ref addler);
                if (status != DecompressStatus.Success)
                {
                    Console.WriteLine("Failed to unpack file registry");
                    return 6;
                }
                byte[] fileRegistryHash = md5.ComputeHash(fileRegistry);
                if (!StructuralComparisons.StructuralEqualityComparer.Equals(fileRegistryHash, header.fileRegistryDigest))
                {
                    Console.WriteLine("File registry hash mismatch");
                    return 8;
                }
                Unpacker unpacker = new Unpacker(fs, br, fileRegistry, directoryListing, outputFolder, header.fileCount);
                unpacker.Unpack();

                return 0;
            }
        }
Example #5
0
 public static DecompressStatus DecompressMemory(DecompressionParameters parameters, byte[] inBuf,int inBufSize, int inBufOffset, byte[] outBuf, ref int outBufSize, int outBufOffset, ref uint adler32)
 {
     return LzhamInterop.DecompressMemory(parameters, outBuf, ref outBufSize, outBufOffset, inBuf, inBufSize, inBufOffset, ref adler32);
 }
Example #6
0
        public static unsafe DecompressStatus DecompressMemory(DecompressionParameters parameters, byte[] outBuf, ref int outBufSize, int outBufOffset, byte[] inBuf, int inBufSize, int inBufOffset, ref uint adler32)
        {
            if (outBufOffset + outBufSize > outBuf.Length)
            {
                throw new ArgumentException("Offset plus count is larger than the length of array", nameof(outBuf));
            }
            if (inBufOffset + inBufSize > inBuf.Length)
            {
                throw new ArgumentException("Offset plus count is larger than the length of array", nameof(inBuf));
            }
            DecompressionParametersInternal p;
            p.m_struct_size = (uint)sizeof(DecompressionParametersInternal);
            p.m_decompress_flags = parameters.Flags;
            p.m_dict_size_log2 = parameters.DictionarySize;
            p.m_table_max_update_interval = parameters.MaxUpdateInterval;
            p.m_table_update_interval_slow_rate = parameters.UpdateIntervalSlowRate;
            p.m_table_update_rate = parameters.UpdateRate;
            if (parameters.SeedBytes != null)
            {
                p.m_num_seed_bytes = (uint) parameters.SeedBytes.Length;
            }

            p.m_struct_size = (uint)sizeof(DecompressionParametersInternal);
            fixed (byte* seedBytes = parameters.SeedBytes)
            fixed (byte* outBytes = outBuf)
            fixed (byte* inBytes = inBuf)
            {
                p.m_pSeed_bytes = seedBytes;
                byte* pBytes = (byte*)&p;
                IntPtr outSize = new IntPtr(outBufSize);
                DecompressStatus result = (DecompressStatus)lzham_decompress_memory(pBytes, outBytes+outBufOffset, ref outSize, inBytes+inBufOffset, inBufSize, ref adler32);
                outBufSize = outSize.ToInt32();
                return result;
            }
        }
Example #7
0
        public static unsafe DecompressionHandle DecompressReinit(DecompressionHandle state, DecompressionParameters parameters)
        {
            DecompressionParametersInternal p;
            p.m_struct_size = (uint)sizeof(DecompressionParametersInternal);
            p.m_decompress_flags = parameters.Flags;
            p.m_dict_size_log2 = parameters.DictionarySize;
            p.m_table_max_update_interval = parameters.MaxUpdateInterval;
            p.m_table_update_interval_slow_rate = parameters.UpdateIntervalSlowRate;
            p.m_table_update_rate = parameters.UpdateRate;
            if (parameters.SeedBytes != null)
            {
                p.m_num_seed_bytes = (uint) parameters.SeedBytes.Length;
            }

            p.m_struct_size = (uint)sizeof(DecompressionParametersInternal);
            fixed (byte* seedBytes = parameters.SeedBytes)
            {
                p.m_pSeed_bytes = seedBytes;
                byte* pBytes = (byte*)&p;
                return lzham_decompress_reinit(state, pBytes);
            }
        }
Example #8
0
        private void WriteFile(string fileName, int offset)
        {
            int size = Marshal.SizeOf(typeof (FileRegistryEntry));
            FileRegistryEntry fileRegistryEntry = Util.ByteArrayToStructure<FileRegistryEntry>(_fileRegistry, offset * size, size);

            string fullName = Path.Combine(_outputFolder, fileName.Trim('\\'));
            string dir = Path.GetDirectoryName(fullName);
            Debug.Assert(dir != null, "dir != null");
            Directory.CreateDirectory(dir);
            _fs.Seek((long)fileRegistryEntry.fileOffset, SeekOrigin.Begin);

            if ((fileRegistryEntry.flag & 1) == 1)
            {
                byte[] inp = _br.ReadBytes((int)fileRegistryEntry.compressed);
                byte[] outp = new byte[fileRegistryEntry.uncompressed];

                DecompressionParameters p = new DecompressionParameters
                {
                    DictionarySize = Util.GetDictLength(fileRegistryEntry.uncompressed),
                    UpdateRate = TableUpdateRate.Fastest
                };
                int u = (int)fileRegistryEntry.uncompressed;
                uint addler = 0;
                DecompressStatus status = Lzham.DecompressMemory(p, inp, inp.Length, 0, outp, ref u, 0, ref addler);

                if (status != DecompressStatus.Success)
                {
                    Console.WriteLine($"Error decompressing file {fileName}. ({status})");
                    Environment.FailFast($"Error decompressing file {fileName}. ({status})");
                }

                File.WriteAllBytes(fullName, outp);
            }
            else
            {
                var hm = _br.ReadBytes((int)fileRegistryEntry.compressed);
                File.WriteAllBytes(fullName, hm);
            }
        }