public void Compress(int level = 5) { Contract.Requires(level.IsNone() || (level >= IO.Compression.ZLib.kNoCompression && level <= IO.Compression.ZLib.kBestCompression)); // Assume the compressed data will be at most the same size as the uncompressed data if (CompressedData == null || CompressedData.Length < (int)mHeader.UncompressedSize) { CompressedData = new byte[mHeader.UncompressedSize]; } else { Array.Clear(CompressedData, 0, CompressedData.Length); } uint adler32; CompressedData = IO.Compression.ZLib.LowLevelCompress(UncompressedData, level, out adler32 /*mHeader.CompressedAdler32*/, CompressedData); mHeader.CompressedAdler32 = Adler32.Compute(CompressedData); if (mHeader.CompressedAdler32 != adler32) { #if false Debug.Trace.Resource.TraceInformation("ZLib.LowLevelCompress returned different adler32 ({0}) than our computations ({1}). Uncompressed adler32={2}", adler32.ToString("X8"), mHeader.CompressedAdler32.ToString("X8"), mHeader.UncompressedAdler32.ToString("X8")); #endif } mHeader.CompressedSize = (ulong)CompressedData.LongLength; }
uint ReadSysenvSeed(ArcView file, IEnumerable <Entry> dir, uint key) { var entry = dir.FirstOrDefault(e => e.Name.Equals("sysenv.tbl", StringComparison.InvariantCultureIgnoreCase)); if (null == entry) { return(key); } var data = file.View.ReadBytes(entry.Offset, entry.Size); if (data.Length <= 4) { throw new InvalidFormatException("Invalid sysenv.tbl size"); } Decrypt(data, entry.Offset, key); uint adler32 = LittleEndian.ToUInt32(data, 0); if (adler32 != Adler32.Compute(data, 4, data.Length - 4)) { throw new InvalidEncryptionScheme(); } using (var input = new MemoryStream(data, 4, data.Length - 4)) using (var sysenv_stream = new ZLibStream(input, CompressionMode.Decompress)) { var seed = new byte[0x10]; if (0x10 != sysenv_stream.Read(seed, 0, 0x10)) { throw new InvalidFormatException("Invalid sysenv.tbl size"); } return(EncryptionScheme.GenerateContentKey(seed)); } }
public void Test_Adler32_computation(byte[] input, uint expected) { unchecked { var actual = Adler32.Compute(input); Assert.Equal((int)expected, actual); } }
byte[] ReadSysenvSeed(ArcView file, Entry entry, uint key) { var data = file.View.ReadBytes(entry.Offset, entry.Size); if (data.Length <= 4) { throw new InvalidFormatException("Invalid sysenv.tbl size"); } Decrypt(data, entry.Offset, key); uint adler32 = LittleEndian.ToUInt32(data, 0); if (adler32 != Adler32.Compute(data, 4, data.Length - 4)) { throw new InvalidEncryptionScheme(); } using (var input = new MemoryStream(data, 4, data.Length - 4)) using (var sysenv_stream = new ZLibStream(input, CompressionMode.Decompress)) { var seed = new byte[0x10]; if (0x10 != sysenv_stream.Read(seed, 0, 0x10)) { throw new InvalidFormatException("Invalid sysenv.tbl size"); } return(seed); } }
public void ReadData(System.IO.Stream s) { UncompressedData = new byte[mHeader.UncompressedSize]; s.Read(UncompressedData, 0, UncompressedData.Length); mHeader.UncompressedAdler32 = Adler32.Compute(UncompressedData); }
public void TestCompute() { var expected = result1; var result = Adler32.Compute(test1, Encoding.ASCII); Assert.AreEqual(expected, result); Assert.IsTrue(result <= (long)uint.MaxValue); }
void Transform(byte[] data, int index, int length) { uint key = Adler32.Compute(data, index, length); data[index + 0x200] ^= (byte)key; data[index + 0x201] ^= (byte)(key >> 8); data[index + 0x202] ^= (byte)(key >> 16); data[index + 0x203] ^= (byte)(key >> 24); }
protected override void DecryptPre(byte[] data, int index, uint length) { uint key = Adler32.Compute(data, index, 0x100); data[index + 0x204] ^= (byte)key; data[index + 0x205] ^= (byte)(key >> 8); data[index + 0x206] ^= (byte)(key >> 16); data[index + 0x207] ^= (byte)(key >> 24); }
public byte[] ReadZlib(byte[] content, int start, int count) { var zlibHeader = new ZlibHeader { CMF = (ZlibCompressionMethodAndFlags)reader.ReadByte(), FLG = (ZlibFlags)reader.ReadByte(), }; if (zlibHeader.Method != ZlibCompressionMethodAndFlags.Deflate) throw new IOException($"Zlib compression method unsupported: {zlibHeader.CMF}"); if ((zlibHeader.FLG & ZlibFlags.Dict) != 0) throw new IOException("Zlib Dict unsupported"); #if XELF_PNGREADER_DISABLE_COMPRESSION var blockHeader = new DeflateBlockHeader { Flags = (DeflateBlockHeaderFlags)reader.ReadByte(), Length = reader.ReadUInt16(), LengthComplement = reader.ReadUInt16(), }; if (blockHeader.Flags != DeflateBlockHeaderFlags.Final) throw new IOException($"Unsupported Deflate Flags: {blockHeader.Flags}"); if (blockHeader.Length != (ushort)~blockHeader.LengthComplement) throw new IOException($"Deflate Block Length corrupted: {blockHeader.Length} {~blockHeader.LengthComplement}"); var bytes = reader.ReadBytes(blockHeader.Length); #else uint adler32; var bytes = new byte[(Width + 1) * Height]; using (var m = new MemoryStream(content, start + 2, count - 6)) { var start2 = 0; using (var deflate = new DeflateStream(m, CompressionMode.Decompress, true)) { do { var read = deflate.Read(bytes, start2, bytes.Length - start2); if (read == 0) break; start2 += read; } while (start2 < bytes.Length); deflate.Close(); //Debug.Log($"{bytes.Length} {count}"); } #endif stream.Position = start + count - 4; //Debug.Log($"s={start} c={count} p={stream.Position} l={content.Length}"); adler32 = ReadSwappedUInt32(); } var computed = Adler32.Compute(bytes, 0, bytes.Length); if (adler32 != computed) { //Debug.Log($"Incorrect Adler32 | file:{adler32:X} computed:{computed:X}"); throw new IOException($"Incorrect Adler32 | file:{adler32:X} computed:{computed:X}"); } var data = GetUnfiltered(bytes); return data; }
void PrepareHeader(KgdMetaData info) { Buffer.BlockCopy(PngFormat.HeaderBytes, 0, m_buffer, 0, 8); BigEndian.Pack(0x0D, m_buffer, 8); BigEndian.Pack(0x49484452, m_buffer, 0x0C); // 'IHDR' BigEndian.Pack(info.Width, m_buffer, 0x10); BigEndian.Pack(info.Height, m_buffer, 0x14); m_buffer[0x18] = info.BitsPerPlane; m_buffer[0x19] = info.ColorType; uint checksum = Adler32.Compute(m_buffer, 0x10, 0x0D); BigEndian.Pack(checksum, m_buffer, 0x1D); m_buffer_size = 0x21; }
Stream UnpackData(byte[] data, int index = 0) { int length = data.Length - index; if (length <= 4) { return(new MemoryStream(data, index, length)); } uint adler32 = LittleEndian.ToUInt32(data, index); if (adler32 != Adler32.Compute(data, index + 4, length - 4)) { return(new MemoryStream(data, index, length)); } var input = new MemoryStream(data, index + 4, length - 4); return(new ZLibStream(input, CompressionMode.Decompress)); }
/// <summary> /// Compresses the data array. /// </summary> /// <param name="data">The data to compress.</param> /// <returns>The compressed data.</returns> private static byte[] CompressData(byte[] data) { var adler = BitConverter.GetBytes(Adler32.Compute(data)); using (var compressedStream = new MemoryStream()) { compressedStream.WriteByte(0x58); compressedStream.WriteByte(0x85); using (var outputStream = new DeflateStream(compressedStream, CompressionMode.Compress, true)) { outputStream.Write(data, 0, data.Length); } compressedStream.WriteByte(adler[3]); compressedStream.WriteByte(adler[2]); compressedStream.WriteByte(adler[1]); compressedStream.WriteByte(adler[0]); return(compressedStream.ToArray()); } }
void FillBuffer() { m_buffer_pos = m_buffer_size = 0; if (m_eof) { return; } if (m_input.PeekByte() == -1) { m_eof = true; BigEndian.Pack(0, m_buffer, 0); BigEndian.Pack(0x49454E44, m_buffer, 4); // 'IEND' BigEndian.Pack(0xAE426082, m_buffer, 8); m_buffer_size = 12; return; } int chunk_size = m_input.ReadInt32(); int type = m_input.ReadByte(); if (type != 2) { m_eof = true; return; } if (chunk_size + 12 > m_buffer.Length) { m_buffer = new byte[chunk_size + 12]; } chunk_size = m_input.Read(m_buffer, 8, chunk_size); BigEndian.Pack(chunk_size, m_buffer, 0); BigEndian.Pack(0x49444154, m_buffer, 4); // 'IDAT' uint checksum = Adler32.Compute(m_buffer, 8, chunk_size); BigEndian.Pack(checksum, m_buffer, 8 + chunk_size); m_buffer_size = 12 + chunk_size; return; }
AzArchive ReadIndex(ArcView file, byte[] header, EncryptionScheme scheme) { int ext_count = LittleEndian.ToInt32(header, 4); int count = LittleEndian.ToInt32(header, 8); uint index_length = LittleEndian.ToUInt32(header, 12); if (ext_count < 1 || ext_count > 8 || !IsSaneCount(count) || index_length >= file.MaxOffset) { return(null); } var packed_index = file.View.ReadBytes(header.Length, index_length); if (packed_index.Length != index_length) { return(null); } Decrypt(packed_index, header.Length, scheme.IndexKey); uint checksum = LittleEndian.ToUInt32(packed_index, 0); if (checksum != Adler32.Compute(packed_index, 4, packed_index.Length - 4)) { if (checksum != Crc32.Compute(packed_index, 4, packed_index.Length - 4)) { throw new InvalidFormatException("Index checksum mismatch"); } } using (var input = new MemoryStream(packed_index, 4, packed_index.Length - 4)) { var dir = ParseIndex(input, count, header.Length + index_length, file.MaxOffset); if (null == dir) { return(null); } uint content_key = GetContentKey(file, dir, scheme); return(new AzArchive(file, this, dir, scheme.IndexKey, content_key)); } }
public static void CompressFromStream(IO.EndianWriter blockStream, System.IO.Stream source, out uint streamAdler, out int streamSize) { Contract.Requires <ArgumentNullException>(blockStream != null); Contract.Requires <ArgumentNullException>(source != null); using (var ms = new System.IO.MemoryStream((int)source.Length + Header.kSizeOf)) using (var s = new IO.EndianStream(ms, Shell.EndianFormat.Big, permissions: FA.Write)) using (var cs = new CompressedStream()) { s.StreamMode = FA.Write; cs.InitializeFromStream(source); cs.Compress(); cs.Serialize(s); ms.Position = 0; streamSize = (int)ms.Length; streamAdler = Adler32.Compute(ms, streamSize); ms.WriteTo(blockStream.BaseStream); } }
AzArchive ReadIndex(ArcView file, byte[] header, EncryptionScheme scheme) { int ext_count = LittleEndian.ToInt32(header, 4); int count = LittleEndian.ToInt32(header, 8); uint index_length = LittleEndian.ToUInt32(header, 12); if (ext_count < 1 || ext_count > 8 || !IsSaneCount(count) || index_length >= file.MaxOffset) { return(null); } var packed_index = file.View.ReadBytes(header.Length, index_length); if (packed_index.Length != index_length) { return(null); } Decrypt(packed_index, header.Length, scheme.IndexKey); uint checksum = LittleEndian.ToUInt32(packed_index, 0); if (checksum != Adler32.Compute(packed_index, 4, packed_index.Length - 4)) { if (checksum != Crc32.Compute(packed_index, 4, packed_index.Length - 4)) { throw new InvalidFormatException("Index checksum mismatch"); } } uint base_offset = (uint)header.Length + index_length; using (var input = new MemoryStream(packed_index, 4, packed_index.Length - 4)) using (var zstream = new ZLibStream(input, CompressionMode.Decompress)) using (var index = new BinaryReader(zstream)) { var dir = new List <Entry> (count); var name_buffer = new byte[0x20]; for (int i = 0; i < count; ++i) { uint offset = index.ReadUInt32(); uint size = index.ReadUInt32(); uint crc = index.ReadUInt32(); index.ReadInt32(); if (name_buffer.Length != index.Read(name_buffer, 0, name_buffer.Length)) { return(null); } var name = Binary.GetCString(name_buffer, 0, 0x20); if (0 == name.Length) { return(null); } var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Offset = base_offset + offset; entry.Size = size; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } uint content_key = GetContentKey(file, dir, scheme); return(new AzArchive(file, this, dir, scheme.IndexKey, content_key)); } }
public static byte[] GenerateChecksum(string checksum, int offset, byte[] buffer, int eof = -1) { byte[] returnValue = null; switch (checksum) { case "Adler8 - {1Bytes}": returnValue = eof == -1 ? Adler8.Compute(offset, buffer) : Adler8.Compute(offset, buffer, eof); break; case "Adler16 - {2Bytes}": returnValue = eof == -1 ? Adler16.Compute(offset, buffer) : Adler16.Compute(offset, buffer, eof); break; case "Adler32 - {4Bytes}": returnValue = eof == -1 ? Adler32.Compute(offset, buffer) : Adler32.Compute(offset, buffer, eof); break; case "Checksum8 - {1Bytes}": returnValue = eof == -1 ? Checksum8.Compute(offset, buffer) : Checksum8.Compute(offset, buffer, eof); break; case "Checksum16 - {2Bytes}": returnValue = eof == -1 ? Checksum16.Compute(offset, buffer) : Checksum16.Compute(offset, buffer, eof); break; case "Checksum24 - {3Bytes}": returnValue = eof == -1 ? Checksum24.Compute(offset, buffer) : Checksum24.Compute(offset, buffer, eof); break; case "Checksum32 - {4Bytes}": returnValue = eof == -1 ? Checksum32.Compute(offset, buffer) : Checksum32.Compute(offset, buffer, eof); break; case "Checksum40 - {5Bytes}": returnValue = eof == -1 ? Checksum40.Compute(offset, buffer) : Checksum40.Compute(offset, buffer, eof); break; case "Checksum48 - {6Bytes}": returnValue = eof == -1 ? Checksum48.Compute(offset, buffer) : Checksum48.Compute(offset, buffer, eof); break; case "Checksum56 - {7Bytes}": returnValue = eof == -1 ? Checksum56.Compute(offset, buffer) : Checksum56.Compute(offset, buffer, eof); break; case "Checksum64 - {8Bytes}": returnValue = eof == -1 ? Checksum64.Compute(offset, buffer) : Checksum64.Compute(offset, buffer, eof); break; case "CRC16 - {2Bytes}": Crc16 crc16 = new Crc16(); returnValue = eof == -1 ? crc16.Compute(offset, buffer) : crc16.Compute(offset, buffer, eof); break; case "CRC16 CCITT - {2Bytes}": Crc16ccitt crc16Ccitt = new Crc16ccitt(); returnValue = eof == -1 ? crc16Ccitt.Compute(offset, buffer) : crc16Ccitt.Compute(offset, buffer, eof); break; case "CRC32 - {4Bytes}": returnValue = eof == -1 ? Crc32.Compute(offset, buffer) : Crc32.Compute(offset, buffer, eof); break; case "HMAC SHA 1 (128) - {16Bytes}": returnValue = eof == -1 ? HmacSha1.Compute(offset, buffer) : HmacSha1.Compute(offset, buffer, eof); break; case "HMAC SHA 256 - {32Bytes}": returnValue = eof == -1 ? HmacSha256.Compute(offset, buffer) : HmacSha256.Compute(offset, buffer, eof); break; case "HMAC SHA 384 - {48Bytes}": returnValue = eof == -1 ? HmacSha384.Compute(offset, buffer) : HmacSha384.Compute(offset, buffer, eof); break; case "HMAC SHA 512 - {64Bytes}": returnValue = eof == -1 ? HmacSha512.Compute(offset, buffer) : HmacSha512.Compute(offset, buffer, eof); break; case "MD5 - {16Bytes}": returnValue = eof == -1 ? Md5.Compute(offset, buffer) : Md5.Compute(offset, buffer, eof); break; case "MD5 CNG - {16Bytes}": returnValue = eof == -1 ? Md5Cng.Compute(offset, buffer) : Md5Cng.Compute(offset, buffer, eof); break; } return(returnValue); }