public static byte[] Comp(byte[] input) { using (var sourceStream = new MemoryStream(input)) { using (var compressed = new MemoryStream()) { using (var zipSteam = new ZlibStream(compressed, CompressionMode.Compress, CompressionLevel.Level9, true)) { zipSteam.FlushMode = FlushType.Full; //var buffer = new byte[1024]; //int len = sourceStream.Read(buffer, 0, buffer.Length); //while (len > 0) //{ // zipSteam.Write(buffer, 0, len); // len = sourceStream.Read(buffer, 0, buffer.Length); //} sourceStream.CopyTo(zipSteam); zipSteam.Flush(); return(compressed.ToArray()); } } } }
public void Compress(string algorithm) { if (algorithm == CompressionAlgorithm.Deflate) { byte[] buffer = _memoryStream.ToArray(); MemoryStream ms = new MemoryStream(); DeflateStream deflateStream = new DeflateStream(ms, CompressionMode.Compress, true); deflateStream.Write(buffer, 0, buffer.Length); deflateStream.Close(); _memoryStream.Close(); _memoryStream = ms; AMFReader amfReader = new AMFReader(_memoryStream); AMFWriter amfWriter = new AMFWriter(_memoryStream); _dataOutput = new DataOutput(amfWriter); _dataInput = new DataInput(amfReader); } if (algorithm == CompressionAlgorithm.Zlib) { byte[] buffer = _memoryStream.ToArray(); MemoryStream ms = new MemoryStream(); ZlibStream zlibStream = new ZlibStream(ms, CompressionMode.Compress, true); zlibStream.Write(buffer, 0, buffer.Length); zlibStream.Flush(); zlibStream.Close(); zlibStream.Dispose(); _memoryStream.Close(); _memoryStream = ms; AMFReader amfReader = new AMFReader(_memoryStream); AMFWriter amfWriter = new AMFWriter(_memoryStream); _dataOutput = new DataOutput(amfWriter); _dataInput = new DataInput(amfReader); } }
public void SetChunkData(byte[] cData, Boolean isCompressed = true) { MemoryStream byteStream = new MemoryStream(); ZlibStream zStream = new ZlibStream(byteStream, CompressionMode.Decompress, CompressionLevel.BestCompression, true); zStream.Write(cData, 0, cData.Length); zStream.Flush(); zStream.Dispose(); zStream = null; byte[] bytes = byteStream.ToArray(); byteStream.Dispose(); byteStream = null; Block b; WorldLocation blockLoc; int x, y, z; // Block Types for (int i = 0; i < 32768; i++) { x = (Location.X * 16) + (i >> 11); y = i & 0x7F; z = (Location.Z * 16) + ((i & 0x780) >> 7); blockLoc = new WorldLocation(x, y, z); b = new Block((BlockType)bytes[i], blockLoc); Blocks.Add(b); } // TODO: Read and handle block/sky light and metadata bytes = null; }
public void Should_compress_and_decompress_using_supported_library() { var text = "Interoperability is so much fun!"; using var output = new MemoryStream(); using (var compressOutput = new ZlibStream(output, CompressionMode.Compress)) { compressOutput.Write(Encoding.UTF8.GetBytes(text)); compressOutput.Flush(); } output.Flush(); var bytes = output.ToArray(); using var input = new MemoryStream(bytes); using var decompressStream = new InflaterInputStream(input); var buffer = new byte[16384]; var length = decompressStream.Read(buffer, 0, buffer.Length); var result = Encoding.UTF8.GetString(buffer, 0, length); Assert.That(result, Is.EqualTo(text)); }
public void WriteBitmap(Bitmap b) { if (disposed) { throw new ObjectDisposedException(GetType().FullName); } if (b.Width != Width) { throw new ArgumentException(String.Format("The width of the supplied bitmap ({0}) must match the width of the output png ({1}).", b.Width, Width)); } BitmapData bData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte[] data = new byte[b.Width * b.Height * 4]; Marshal.Copy(bData.Scan0, data, 0, data.Length); b.UnlockBits(bData); if (dstream == null) { dstream = new DataStream(); } if (zstream == null) { zstream = new ZlibStream(dstream, CompressionMode.Compress); } byte[] filterType = new byte[] { 0 }; //none byte[] pixel = new byte[4]; int lineWidth = b.Width * 4; for (int y = 0; y < b.Height; y++) { zstream.Write(filterType, 0, 1); for (int x = 0; x < b.Width; x++) { int offset = y * lineWidth + x * 4; //needs to be rgba if (BitConverter.IsLittleEndian) { pixel[2] = data[offset]; //b pixel[1] = data[offset + 1]; //g pixel[0] = data[offset + 2]; //r pixel[3] = data[offset + 3]; //a } else { pixel[3] = data[offset]; //a pixel[0] = data[offset + 1]; //r pixel[1] = data[offset + 2]; //g pixel[2] = data[offset + 3]; //b } zstream.Write(pixel, 0, 4); } } zstream.Flush(); WriteChunk("IDAT", dstream.GetDataSoFar()); }
private byte[] Inflate(byte[] buffer, int sizeDecompressed, out int sizeCompressed, int compressionLevel) { MemoryStream memoryStream = new MemoryStream(); ZlibStream zlibStream = new ZlibStream(memoryStream, CompressionMode.Compress, (CompressionLevel)compressionLevel, leaveOpen: true); zlibStream.Write(buffer, 0, sizeDecompressed); zlibStream.Flush(); zlibStream.Close(); sizeCompressed = (int)memoryStream.Length; return(memoryStream.ToArray()); }
/// <summary> /// Compress to CompressedData /// </summary> public static MemoryStream Compress(byte[] buffer) { var output = new MemoryStream(); using (ZlibStream zout = new ZlibStream(output, CompressionMode.Compress)) { zout.Write(buffer, 0, buffer.Length); zout.Flush(); } return(output); }
public byte[] GetChunkData() { MemoryStream byteStream = new MemoryStream(); byte[] bytes = new byte[Blocks.Count + ((Blocks.Count / 2) * 3)]; int index; foreach (Block b in Blocks) { index = b.Location.Y + ((b.Location.Z - (Location.Z * 16)) * (SizeY + 1)) + ((b.Location.X - (Location.X * 16)) * (SizeY + 1) * (SizeZ + 1)); byteStream.Seek(index, SeekOrigin.Begin); byteStream.WriteByte((byte)b.Type); } byteStream.Seek(Blocks.Count, SeekOrigin.Begin); for (int a = 1; a <= 3; a++) { for (int b = 0; b < 16384; b++) { switch (a) { case 1: byteStream.WriteByte(0xFF); break; default: byteStream.WriteByte(0xFF); break; } } } bytes = byteStream.ToArray(); byteStream.Dispose(); byteStream = null; // Compress array MemoryStream ms = new MemoryStream(); ZlibStream zs = new ZlibStream(ms, CompressionMode.Compress, CompressionLevel.Default, true); zs.Write(bytes, 0, bytes.Length); zs.Flush(); zs.Dispose(); zs = null; byte[] finalBytes = ms.ToArray(); ms.Dispose(); ms = null; bytes = null; // return(finalBytes); }
public byte[] Inflate(byte[] buffer, int sizeDecompressed, out int sizeCompressed, int compressionLevel) { MemoryStream output = new MemoryStream(); ZlibStream zs = new ZlibStream(output, CompressionMode.Compress, (CompressionLevel)compressionLevel, true); zs.Write(buffer, 0, sizeDecompressed); zs.Flush(); zs.Close(); sizeCompressed = (int)output.Length; return(output.ToArray()); }
public static int Compress(byte[] inbuf, byte[] outbuf, int level) { using (var ms = new MemoryStream(outbuf)) { using (var outStream = new ZlibStream(ms, CompressionMode.Compress, (CompressionLevel)level)) { outStream.Write(inbuf, 0, inbuf.Length); outStream.Flush(); return((int)ms.Position); } } }
public static byte[] Compress(byte[] inbuf, int level) { using (var ms = new MemoryStream()) { using (var outStream = new ZlibStream(ms, CompressionMode.Compress, (CompressionLevel)level)) { outStream.Write(inbuf, 0, inbuf.Length); outStream.Flush(); return(ms.ToArray()); } } }
/// <summary> /// Saves the game to disk in the background. /// </summary> /// <param name="data">The uncompressed save data.</param> private void DoSave(BackgroundSaveData data) { try { var stream = data.Stream; PUtil.LogDebug("Background save to: " + data.FileName); stream.Seek(0L, SeekOrigin.Begin); CleanAutosaves(data.FileName); // Write the file header using (var writer = new BinaryWriter(File.Open(data.FileName, FileMode. Create))) { var saveHeader = SaveGame.Instance.GetSaveHeader(true, data.Compress, out SaveGame.Header header); writer.Write(header.buildVersion); writer.Write(header.headerSize); writer.Write(header.headerVersion); writer.Write(header.compression); writer.Write(saveHeader); KSerialization.Manager.SerializeDirectory(writer); writer.Flush(); if (data.Compress) { // SaveLoader.CompressContents is now private using (var compressor = new ZlibStream(writer.BaseStream, CompressionMode.Compress, CompressionLevel.BestSpeed)) { stream.CopyTo(compressor); compressor.Flush(); } } else { stream.CopyTo(writer.BaseStream); } } status = SaveStatus.Done; PUtil.LogDebug("Background save complete"); } catch (IOException e) { // Autosave error! PUtil.LogExcWarn(e); status = SaveStatus.IOError; } catch (Exception e) { // Allowing it to continue here will crash with a simdll error PUtil.LogException(e); status = SaveStatus.Failed; } finally { try { // Cannot throw during a finally, or it will discard the original exception data.Dispose(); } catch (Exception e) { PUtil.LogException(e); } } }
private RecyclableMemoryStream Inflate(byte[] buffer, long bufferlength, int sizeDecompressed, out int sizeCompressed, CompressionLevel compressionLevel) { RecyclableMemoryStream output = new RecyclableMemoryStream(); using (ZlibStream zs = new ZlibStream(output, CompressionMode.Compress, compressionLevel, true)) { zs.Write(buffer, 0, (int)bufferlength); zs.Flush(); } sizeCompressed = (int)output.Length; output.Position = 0; return(output); }
public static byte[] CompressContents(byte[] uncompressed, int length) { using (MemoryStream memoryStream = new MemoryStream(length)) { using (ZlibStream zlibStream = new ZlibStream(memoryStream, CompressionMode.Compress, CompressionLevel.BestSpeed)) { zlibStream.Write(uncompressed, 0, length); zlibStream.Flush(); } memoryStream.Flush(); return(memoryStream.ToArray()); } }
internal void Deserialize() { MessagePackSerializer <List <T> > messagePackSerializer = MessagePackSerializer.Create <List <T> >(); ZlibStream zs = new ZlibStream(this.Stream, CompressionMode.Decompress); MemoryStream ms = new MemoryStream(); zs.CopyTo(ms); zs.Flush(); ms.Flush(); ms.Position = 0; this.DataSlice = messagePackSerializer.Unpack(ms); ms.Close(); }
private static void DecompressZlib(Stream compressed, Stream target) { var zip = new ZlibStream(compressed, CompressionMode.Decompress); int readBytes; var buffer = new byte[512]; do { readBytes = zip.Read(buffer, 0, buffer.Length); target.Write(buffer, 0, readBytes); } while (readBytes > 0); zip.Flush(); target.Seek(0, SeekOrigin.Begin); }
internal void Serialize() { MessagePackSerializer <List <T> > bf = MessagePackSerializer.Create <List <T> >(); MemoryStream ms = new MemoryStream(); bf.Pack(ms, this.DataSlice); ZlibStream zs = new ZlibStream(this.Stream, CompressionMode.Compress, CompressionLevel.Level9); zs.FlushMode = FlushType.Sync; ms.Position = 0; ms.CopyTo(zs); zs.FlushMode = FlushType.Full; zs.Flush(); this.Stream.Position = 0; }
public byte[] CompressChunk() { //File and body headers ar emanaged outside //All we do here is to write the compressed tag using (MemoryStream ms = new MemoryStream()) { using (ZlibStream compressed = new ZlibStream(ms, CompressionMode.Compress, true)) { var w = new EndianBinaryWriter(EndianBitConverter.Big, compressed); Tag.Write(w); compressed.Flush(); } return(ms.ToArray()); } }
public static byte[] ZibDecompress(byte[] data) { var ms = new MemoryStream(data); using (var msDecompressed = new System.IO.MemoryStream()) { using (var zs = new ZlibStream(msDecompressed, CompressionMode.Decompress, true)) { int readByte = ms.ReadByte(); while (readByte != -1) { zs.WriteByte((byte)readByte); readByte = ms.ReadByte(); } zs.Flush(); } return(msDecompressed.ToArray()); } }
/// <summary> /// /// </summary> /// <remarks> /// Credits to enohka for this code. /// See more at: http://github.com/enohka/moddingSuite /// </remarks> public byte[] Compress(byte[] input) { using (var sourceStream = new MemoryStream(input)) { using (var compressed = new MemoryStream()) { using (var zipSteam = new ZlibStream(compressed, CompressionMode.Compress, CompressionLevel.Level9, true)) { zipSteam.FlushMode = FlushType.Full; sourceStream.CopyTo(zipSteam); zipSteam.Flush(); return(compressed.ToArray()); } } } }
public static byte[] Decompress(string inFile) { using (var outStream = new MemoryStream()) { using (var zOutputStream = new ZlibStream(outStream, CompressionMode.Decompress)) { using (var inFileStream = new FileStream(inFile, FileMode.Open)) { var buffer = new byte[2000]; int len; while ((len = inFileStream.Read(buffer, 0, 2000)) > 0) { zOutputStream.Write(buffer, 0, len); } zOutputStream.Flush(); return(outStream.ToArray()); } } } }
internal static unsafe T[] Compress <T>(ReadOnlySpan <byte> data) where T : unmanaged { if (typeof(T) == typeof(byte)) { return((T[])(object)CompressBytes(data)); } long requiredSize = CompressedLengthMax(data); long capacity = AlignCount <T>(requiredSize); if (capacity > int.MaxValue) { var resultArray = CompressBytes(data); T[] copiedResult = GC.AllocateUninitializedArray <T>(AlignCount <T>(resultArray.Length)); resultArray.AsReadOnlySpan().CopyTo(copiedResult.AsSpan().AsBytes()); return(copiedResult); } T[] result = GC.AllocateUninitializedArray <T>((int)capacity); long resultLength; fixed(T *resultPtr = result) { using var resultStream = new UnmanagedMemoryStream((byte *)resultPtr, result.Length * sizeof(T)); using var compressor = new ZlibStream(resultStream, CompressionMode.Compress, CompressionLevel.BestCompression); SetStrategy?.Invoke(compressor, CompressionStrategy.Filtered); compressor.Write(data.ToArray(), 0, data.Length); compressor.Flush(); resultLength = AlignCount <T>(compressor.TotalOut); } if (result.Length != resultLength) { Array.Resize(ref result, (int)resultLength); } return(result); }
/// <summary> /// Compresses the byte array using zlib compression. The entire byte array is compressed. /// </summary> /// <param name="algorithm">The compression algorithm to use when compressing. Valid values are defined as constants in the CompressionAlgorithm class. The default is to use zlib format.</param> /// <remarks> /// After the call, the Length property of the ByteArray is set to the new length. The position property is set to the end of the byte array. /// </remarks> public void Compress(string algorithm) { ValidationUtils.ArgumentConditionTrue(algorithm == CompressionAlgorithm.Deflate || algorithm == CompressionAlgorithm.Zlib, "algorithm", "Invalid parameter"); #if SILVERLIGHT throw new NotSupportedException(); #else if (algorithm == CompressionAlgorithm.Deflate) { byte[] buffer = _memoryStream.ToArray(); MemoryStream ms = new MemoryStream(); DeflateStream deflateStream = new DeflateStream(ms, CompressionMode.Compress, true); deflateStream.Write(buffer, 0, buffer.Length); deflateStream.Close(); _memoryStream.Close(); _memoryStream = ms; AMFReader amfReader = new AMFReader(_memoryStream); AMFWriter amfWriter = new AMFWriter(_memoryStream); _dataOutput = new DataOutput(amfWriter); _dataInput = new DataInput(amfReader); } if (algorithm == CompressionAlgorithm.Zlib) { byte[] buffer = _memoryStream.ToArray(); MemoryStream ms = new MemoryStream(); ZlibStream zlibStream = new ZlibStream(ms, CompressionMode.Compress, true); zlibStream.Write(buffer, 0, buffer.Length); zlibStream.Flush(); zlibStream.Close(); zlibStream.Dispose(); _memoryStream.Close(); _memoryStream = ms; AMFReader amfReader = new AMFReader(_memoryStream); AMFWriter amfWriter = new AMFWriter(_memoryStream); _dataOutput = new DataOutput(amfWriter); _dataInput = new DataInput(amfReader); } #endif }
/// <summary> /// Compress the incoming stream to a file using zlib compression starting at the incoming offset. /// </summary> /// <param name="pStream">Stream to compress.</param> /// <param name="pOutputFilePath">Path to the file to output.</param> /// <param name="pStartingOffset">Offset within the stream to start compressing.</param> public static void CompressStreamToZlibFile(Stream pStream, string pOutputFilePath, long pStartingOffset) { using (FileStream outFs = new FileStream(pOutputFilePath, FileMode.Create, FileAccess.Write)) { using (BinaryReader br = new BinaryReader(pStream)) { pStream.Position = pStartingOffset; using (ZlibStream zs = new ZlibStream(outFs, CompressionMode.Compress, Ionic.Zlib.CompressionLevel.BestCompression, true)) { int read; byte[] data = new byte[Constants.FileReadChunkSize]; while ((read = br.Read(data, 0, data.Length)) > 0) { zs.Write(data, 0, read); } zs.Flush(); } } } }
/// <summary> /// Create compressed byte array /// </summary> /// <returns>compressed data</returns> public static byte[] CreateExplorationData() { var result = new MemoryStream(); using (var gz = new ZlibStream(result, CompressionMode.Compress, CompressionLevel.BestCompression)) { using (var binaryWriter = new BinaryWriter(gz)) { var idx = 0; var state = Minimap.instance.m_explored[0]; binaryWriter.Write(state); var count = 0; var length = Minimap.instance.m_explored.Length; while (idx < length) { while (idx < length && state == Minimap.instance.m_explored[idx]) { count++; idx++; } state = !state; binaryWriter.Write(count); count = 0; } binaryWriter.Flush(); gz.Flush(); } return(result.ToArray()); } }
public static void Encode(Image image, Stream stream) { var bw = new BinaryWriter(stream, Encoding.Default, leaveOpen: true); bw.Write(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }); void WriteChunk(string type, byte[] data) { Debug.Assert(type.Length == 4); bw.WriteBe(data.Length); var td = Encoding.ASCII.GetBytes(type).Concat(data).ToArray(); bw.Write(td); bw.WriteBe(Crc32Algorithm.Compute(td)); } void Chunk(string type, Action <BinaryWriter> func) { using (var ms = new MemoryStream()) using (var sbw = new BinaryWriter(ms)) { func(sbw); sbw.Flush(); WriteChunk(type, ms.ToArray()); } } Chunk("IHDR", w => { w.WriteBe(image.Size.Width); w.WriteBe(image.Size.Height); w.Write((byte)8); switch (image.ColorMode) { case ColorMode.Greyscale: w.Write((byte)0); break; case ColorMode.Rgb: w.Write((byte)2); break; case ColorMode.Rgba: w.Write((byte)6); break; default: throw new NotImplementedException(); } w.Write((byte)0); // Compression mode w.Write((byte)0); // Filter w.Write((byte)0); // Interlace }); var ps = Image.PixelSize(image.ColorMode); var stride = image.Size.Width * ps; var imem = new byte[image.Size.Height + image.Size.Width * image.Size.Height * ps]; // One byte per scanline for filter (0) for (var y = 0; y < image.Size.Height; ++y) { Array.Copy(image.Data, y * stride, imem, y * stride + y + 1, stride); } using (var ms = new MemoryStream()) { using (var ds = new ZlibStream(ms, CompressionMode.Compress, CompressionLevel.Default, leaveOpen: true)) { ds.Write(imem, 0, imem.Length); ds.Flush(); } ms.Flush(); WriteChunk("IDAT", ms.ToArray()); } Chunk("IEND", w => { }); bw.Flush(); }
public static Image Decode(Stream stream) { var br = new BeBinaryReader(stream, Encoding.Default, leaveOpen: true); ColorMode colorMode = ColorMode.Greyscale; var size = (Width : 0, Height : 0); byte[] data = null; var header = br.ReadBytes(8); var idats = new List <byte[]>(); var running = true; while (running) { var dlen = br.ReadInt32(); var type = Encoding.ASCII.GetString(br.ReadBytes(4)); switch (type) { case "IHDR": size = (br.ReadInt32(), br.ReadInt32()); br.ReadByte(); switch (br.ReadByte()) { case 0: colorMode = ColorMode.Greyscale; break; case 2: colorMode = ColorMode.Rgb; break; case 6: colorMode = ColorMode.Rgba; break; default: throw new NotImplementedException(); } data = new byte[size.Width * size.Height * Image.PixelSize(colorMode)]; br.ReadByte(); br.ReadByte(); br.ReadByte(); break; case "IDAT": idats.Add(br.ReadBytes(dlen)); break; case "IEND": running = false; break; default: br.ReadBytes(dlen); break; } br.ReadUInt32(); } var idata = idats.SelectMany(x => x).ToArray(); using (var ms = new MemoryStream()) using (var zs = new ZlibStream(ms, CompressionMode.Decompress)) { zs.Write(idata, 0, idata.Length); zs.Flush(); ms.Flush(); var tdata = ms.GetBuffer(); var ps = Image.PixelSize(colorMode); var stride = size.Width * ps; for (var y = 0; y < size.Height; ++y) { Array.Copy(tdata, y * stride + y + 1, data, stride * y, stride); switch (tdata[y * stride + y]) { case 0: break; case 1: { for (var x = ps; x < stride; ++x) { data[y * stride + x] = unchecked ((byte)(data[y * stride + x] + data[y * stride + x - ps])); } break; } case 2: { if (y == 0) { break; } for (var x = 0; x < stride; ++x) { data[y * stride + x] = unchecked ((byte)(data[y * stride + x] + data[y * stride + x - stride])); } break; } case 4: { byte Paeth(byte a, byte b, byte c) { int p = a + b - c, pa = p > a ? p - a : a - p, pb = p > b ? p - b : b - p, pc = p > c ? p - c : c - p; return(pa <= pb && pa <= pc ? a : pb <= pc ? b : c); } for (var x = 0; x < stride; ++x) { byte mod = 0; if (x < ps) { if (y > 0) { mod = Paeth(0, data[(y - 1) * stride + x], 0); } } else { mod = y == 0 ? Paeth(data[y * stride + x - ps], 0, 0) : Paeth(data[y * stride + x - ps], data[(y - 1) * stride + x], data[(y - 1) * stride + x - ps]); } data[y * stride + x] = unchecked ((byte)(data[y * stride + x] + mod)); } break; } case byte x: throw new NotImplementedException($"Unsupported filter mode {x}"); } } } return(new Image(colorMode, size, data)); }
/// <summary> /// Sends a rectangle using basic compression. /// </summary> /// <param name="stream"> /// The <see cref="Stream"/> which represents connectivity with the client. /// </param> /// <param name="pixelFormat"> /// The pixel format to use. /// </param> /// <param name="region"> /// The rectangle to send. /// </param> /// <param name="contents"> /// A buffer holding the raw pixel data for the rectangle. /// </param> protected int SendWithBasicCompression(Stream stream, VncPixelFormat pixelFormat, VncRectangle region, byte[] contents) { if (contents.Length < 12) { var compressionControl = TightCompressionControl.BasicCompression; stream.WriteByte((byte)compressionControl); // If the data size after applying the filter but before the compression is less then 12, then the data is sent as is, uncompressed. byte[] encodedBuffer = new byte[4]; var length = WriteEncodedValue(encodedBuffer, 0, (int)contents.Length); stream.Write(encodedBuffer, 0, length); stream.Write(contents, 0, contents.Length); return(1 + length + contents.Length); } else { var compressionControl = TightCompressionControl.BasicCompression | TightCompressionControl.ResetStream0 | TightCompressionControl.UseStream0; var compressionLevel = GetCompressionLevel(this.VncServerSession); stream.WriteByte((byte)compressionControl); using (var buffer = new MemoryStream()) using (var deflater = new ZlibStream(buffer, CompressionMode.Compress, compressionLevel)) { // The Tight encoding makes use of a new type TPIXEL (Tight pixel). This is the same as a PIXEL for the agreed // pixel format, except where true-colour-flag is non-zero, bits-per-pixel is 32, depth is 24 and all of the bits // making up the red, green and blue intensities are exactly 8 bits wide. // In this case a TPIXEL is only 3 bytes long, where the first byte is the red component, the second byte is the // green component, and the third byte is the blue component of the pixel color value. if (pixelFormat.BitsPerPixel == 32 && pixelFormat.BitDepth == 24 && pixelFormat.BlueBits == 8 && pixelFormat.RedBits == 8 && pixelFormat.GreenBits == 8 && !pixelFormat.IsPalettized) { Debug.Assert(contents.Length % 4 == 0, "The size of the raw pixel data must be a multiple of 4 when using a 32bpp pixel format."); int redOffset = pixelFormat.RedShift / 8; int blueOffset = pixelFormat.BlueShift / 8; int greenOffset = pixelFormat.GreenShift / 8; for (int i = 0; i < contents.Length; i += 4) { if (i == contents.Length - 4) { deflater.FlushMode = FlushType.Full; } // The first byte is the red component, the second byte is the // green component, and the third byte is the blue component of the pixel color value. deflater.Write(contents, i + redOffset, 1); deflater.Write(contents, i + greenOffset, 1); deflater.Write(contents, i + blueOffset, 1); } } else { deflater.FlushMode = FlushType.Finish; deflater.Write(contents, 0, contents.Length); } deflater.Flush(); byte[] encodedBuffer = new byte[4]; var length = WriteEncodedValue(encodedBuffer, 0, (int)buffer.Length); stream.Write(encodedBuffer, 0, length); buffer.Position = 0; buffer.CopyTo(stream); return((int)buffer.Length + 1); } } }
public void Write(Context ctx, Stream input, Stream output, Coordinator pc) { try { long imageSize = pc.OutputSize; string junkId; pc.WriterCheckPoint1WriteReady(out junkId); //wait until read has written the header and set the length MemorySection ms = new MemorySection(new byte[4 + 4 + 8 + 8 + 4 + 4]); int blockSize = 0x4000; int blocks = (int)(imageSize / blockSize) + (imageSize % blockSize == 0 ? 0 : 1); ms.WriteUInt32L(0x00, 0xB10BC001); ms.WriteUInt32L(0x04, 0); //insert NKIT later ms.WriteUInt64L(0x08, 0); //size place holder ms.WriteUInt64L(0x10, (ulong)imageSize); ms.WriteUInt32L(0x18, (uint)blockSize); ms.WriteUInt32L(0x1C, (uint)blocks); MemorySection pnt = new MemorySection(new byte[blocks * 8]); MemorySection hsh = new MemorySection(new byte[blocks * 4]); long offset = 0; NCrc crc = new NCrc(); CryptoStream target = new CryptoStream(output, crc, CryptoStreamMode.Write); target.Write(ms.Data, 0, (int)ms.Size); crc.Snapshot("Header"); target.Write(pnt.Data, 0, (int)pnt.Size); crc.Snapshot("Pointers"); target.Write(hsh.Data, 0, (int)hsh.Size); crc.Snapshot("Hashes"); long dataOffset = (pnt.Size + hsh.Size + ms.Size); //fso.position int rdBlk = 0; int wrBlk = 0; object rdBlkLock = new object(); object wrBlkLock = new object(); Task[] tasks = new Task[3]; ManualResetEvent mr = new ManualResetEvent(false); for (int i = 0; i < tasks.Length; i++) //4 threads { tasks[i] = (new TaskFactory()).StartNew((Object prm) => { ManualResetEvent m = (ManualResetEvent)prm; int blkIdx; byte[] rawBlk = new byte[blockSize]; byte[] buff = new byte[blockSize + 0x100]; using (MemoryStream blk = new MemoryStream(buff)) { while (true) { lock (rdBlkLock) { blkIdx = rdBlk++; if (blkIdx >= blocks) { return; //no more processing } int read = input.Read(rawBlk, 0, (int)Math.Min(imageSize - (blkIdx * blockSize), blockSize)); if (read != blockSize) { Array.Clear(rawBlk, read, blockSize - read); } } blk.Position = 0; ZlibStream zl = new ZlibStream(blk, SharpCompress.Compressors.CompressionMode.Compress, SharpCompress.Compressors.Deflate.CompressionLevel.BestCompression, Encoding.Default); zl.FlushMode = FlushType.Finish; zl.Write(rawBlk, 0, blockSize); zl.Flush(); while (blkIdx != wrBlk) { m.WaitOne(); } mr.Reset(); if (blk.Position < blockSize) { target.Write(buff, 0, (int)blk.Position); pnt.WriteUInt64L(blkIdx * 8, (ulong)(offset)); hsh.WriteUInt32L(blkIdx * 4, adler32(buff, (int)blk.Position)); offset += (int)blk.Position; } else { target.Write(rawBlk, 0, blockSize); pnt.WriteUInt64L(blkIdx * 8, (ulong)(offset) | 0x8000000000000000); hsh.WriteUInt32L(blkIdx * 4, adler32(rawBlk, blockSize)); offset += (int)blockSize; } target.Flush(); wrBlk++; mr.Set(); } } }, mr); } Task.WaitAll(tasks); crc.Snapshot("Files"); NCrc readerCrcs; uint validationCrc; pc.WriterCheckPoint2Complete(out readerCrcs, out validationCrc, null, dataOffset + offset); //wait until reader has completed and get crc patches. ms.WriteUInt64L(0x08, (ulong)offset); crc.Crcs[0].PatchCrc = Crc.Compute(ms.Data); crc.Crcs[0].PatchData = ms.Data; crc.Crcs[1].PatchCrc = Crc.Compute(pnt.Data); crc.Crcs[1].PatchData = pnt.Data; crc.Crcs[2].PatchCrc = Crc.Compute(hsh.Data); crc.Crcs[2].PatchData = hsh.Data; ms.WriteUInt32B(0x04, CrcForce.Calculate(crc.FullCrc(true), output.Length, readerCrcs.FullCrc(true), 0x04, ms.ReadUInt32B(0x04))); //magic to force crc crc.Crcs[0].PatchCrc = Crc.Compute(ms.Data); pc.WriterCheckPoint3ApplyPatches(crc, false, crc.FullCrc(true), crc.FullCrc(true), this.VerifyIsWrite, "GCZ Written"); } catch (Exception ex) { throw pc.SetWriterException(ex, "GczWriter.Write - Compress"); } }
public void Save(Stream stream) { long dataStart = CalculateDataStartOffset(); stream.Seek(dataStart, SeekOrigin.Begin); long fileStart = 0; long compressedSize = 0; long uncompressedSize = 0; // Output file data ZlibStream dataStream = null; if (IsCompressed && IsCondensed) { dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true); dataStream.FlushMode = FlushType.Sync; } long compressedStart = 0; for (int i = 0; i < Files.Count; i++) { IPackfileEntry entry = Files[i]; Stream fs = m_Streams[entry.Name]; bool isLast = (i == (Files.Count - 1)); PackfileEntry pfE = (PackfileEntry)entry; var data = pfE.Data; data.Start = (uint)fileStart; data.Size = (uint)fs.Length; data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1; if (this.IsCompressed) { data.Flags = PackfileEntryFlags.Compressed; } if (IsCompressed && IsCondensed) { fs.CopyTo(dataStream); dataStream.Flush(); long afterData = dataStream.TotalOut; data.CompressedSize = (uint)(afterData - compressedStart); compressedStart = afterData; if (IsStr2) { fileStart += data.Size.Align(16); uncompressedSize += data.Size.Align(16); compressedSize += data.CompressedSize; } else { fileStart += data.Size; //.Align(16); if (!isLast) { uncompressedSize += data.Size; //.Align(16); //uint toSkip = data.Size.Align(16) - data.Size; // for (int j = 0; j < toSkip; j++) //dataStream.WriteByte(0); } else { uncompressedSize += data.Size; } compressedSize += data.CompressedSize; } } else if (IsCondensed) { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size.Align(16); if (isLast) { uncompressedSize += data.Size; } else { uint toSkip = data.Size.Align(16) - data.Size; uncompressedSize += data.Size.Align(16); stream.Seek(toSkip, SeekOrigin.Current); } } else if (IsCompressed) { long beforeData = stream.Position; using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true)) { dataStream.FlushMode = FlushType.Sync; fs.CopyTo(dataStream); dataStream.Flush(); } long afterData = stream.Position; data.CompressedSize = (uint)(afterData - beforeData); fileStart += data.CompressedSize; uncompressedSize += data.Size; compressedSize += data.CompressedSize; } else { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size; uncompressedSize += data.Size; } fs.Close(); pfE.Data = data; } if (IsCompressed && IsCondensed) { dataStream.Close(); } // Output file names stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); long startOffset = CalculateEntryNamesOffset(); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.Align(2); pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset); stream.WriteAsciiNullTerminatedString(entry.Name); stream.Seek(1, SeekOrigin.Current); stream.Align(2); } long nameSize = stream.Position - CalculateEntryNamesOffset(); // Output file info stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.WriteStruct(pfE.Data); } long dirSize = stream.Position - GetEntryDataOffset(); // Output header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x0A; FileData.HeaderChecksum = 0; FileData.FileSize = (uint)stream.Length; FileData.NumFiles = (uint)Files.Count; FileData.DirSize = (uint)dirSize; FileData.FilenameSize = (uint)nameSize; FileData.DataSize = (uint)uncompressedSize; if (IsCompressed) { FileData.CompressedDataSize = (uint)compressedSize; } else { FileData.CompressedDataSize = 0xFFFFFFFF; } stream.WriteStruct(FileData); uint checksum = 0; byte[] checksumBuffer = new byte[0x1C]; stream.Seek(0x0C, SeekOrigin.Begin); stream.Read(checksumBuffer, 0, checksumBuffer.Length); checksum = Hashes.CrcVolition(checksumBuffer); stream.Seek(0x08, SeekOrigin.Begin); stream.WriteUInt32(checksum); stream.Flush(); }