internal static byte[] Compress(byte[] bytesToCompress, CompressionFlavor flavor) { if (bytesToCompress == null) { throw new InvalidDataException("Cannot compress null array"); } if (flavor == CompressionFlavor.StoreUncompressed) { throw new InvalidOperationException("Chunk format cannot be used for uncompressed data"); } MemoryStream output = new MemoryStream(bytesToCompress.Length); BinaryWriter writer = new BinaryWriter(output); writer.Write(Chunk.Header); writer.Write(Chunk.DefaultVersion); writer.Write((byte)CompressionMethod.ZLib); writer.Write(NoObfuscation); using (MemoryStream compressedStream = new MemoryStream(bytesToCompress.Length)) { compressedStream.WriteByte(0x78); //ZLib header first byte compressedStream.WriteByte(0xDA); //ZLib header second byte switch (flavor) { case CompressionFlavor.ZLibDeflate: using (DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionLevel.Optimal, true)) deflateStream.Write(bytesToCompress, 0, bytesToCompress.Length); break; case CompressionFlavor.i5ZopfliDeflate: case CompressionFlavor.i10ZopfliDeflate: case CompressionFlavor.i15ZopfliDeflate: if (bytesToCompress.Length < Strategy.ZopfliBreakEven) //Skip Zopfli if file is small { goto case CompressionFlavor.ZLibDeflate; } ZopfliDeflater zstream = new ZopfliDeflater(compressedStream); zstream.NumberOfIterations = (int)flavor; zstream.MasterBlockSize = 0; zstream.Deflate(bytesToCompress, true); break; default: throw new InvalidOperationException("Unknow compression flavor"); } var compressedDataArray = compressedStream.ToArray(); //Change to stream int checksum = ComputeChecksum(compressedDataArray); //Change to stream writer.Write(compressedDataArray.Length); writer.Write(bytesToCompress.Length); writer.Write(checksum); writer.Write(compressedDataArray); } return(output.ToArray()); }
internal void CompressIDAT(bool useZopfli) { byte[] data = idat.GetChunkData(); using (MemoryStream inputStream = new MemoryStream(data, 2, data.Length - 6)) { using (MemoryStream tempStream = new MemoryStream()) { using (DeflateStream inflateStream = new DeflateStream(inputStream, CompressionMode.Decompress, true)) { inflateStream.CopyTo(tempStream); } //ZOutputStream zOutputStream1 = new ZOutputStream(tempStream); //CopyStream(inputStream, zOutputStream1); //zOutputStream1.Flush(); tempStream.Position = 0; using (MemoryStream outputStream = new MemoryStream()) { if (useZopfli) { outputStream.Write(zlibBestCompressionFlag, 0, 2); byte[] dataRaw = new byte[tempStream.Length]; tempStream.Read(dataRaw, 0, dataRaw.Length); ZopfliDeflater zopfliDeflater = new ZopfliDeflater(outputStream); zopfliDeflater.Deflate(dataRaw, false); } else { ZOutputStream zOutputStream = new ZOutputStream(outputStream, zlibConst.Z_NO_COMPRESSION); CopyStream(tempStream, zOutputStream); zOutputStream.Flush(); //outputStream.Write(zlibNoCompressionFlag, 0, 2); //using (DeflateStream deflateStream = new DeflateStream(outputStream, CompressionLevel.NoCompression, true)) //{ // tempStream.CopyTo(deflateStream, 34572); //} } byte[] dataNew = new byte[outputStream.Length]; outputStream.Position = 0; outputStream.Read(dataNew, 0, dataNew.Length); for (int j = 0; j < dataNew.Length; j++) { if (data[j] != dataNew[j]) { Console.WriteLine("{0:D}", j); } } idat.SetChunkData(dataNew); idat.Refresh(); } } } }