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; }
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(); }
public LzhamStream(Stream stream, DecompressionParameters mode) : this(stream, mode, false) { }
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; } }
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); }
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; } }
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); } }
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); } }