Beispiel #1
0
        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());
                    }
                }
            }
        }
Beispiel #2
0
 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);
     }
 }
Beispiel #3
0
        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));
        }
Beispiel #5
0
        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());
        }
Beispiel #6
0
        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());
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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());
        }
Beispiel #10
0
 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);
         }
     }
 }
Beispiel #11
0
 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());
         }
     }
 }
Beispiel #12
0
 /// <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);
         }
     }
 }
Beispiel #13
0
        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);
        }
Beispiel #14
0
 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());
     }
 }
Beispiel #15
0
        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();
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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;
        }
Beispiel #18
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());
            }
        }
Beispiel #19
0
        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());
            }
        }
Beispiel #20
0
        /// <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());
                    }
                }
            }
        }
Beispiel #21
0
        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());
                    }
                }
            }
        }
Beispiel #22
0
    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);
    }
Beispiel #23
0
        /// <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
        }
Beispiel #24
0
        /// <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();
                    }
                }
            }
        }
Beispiel #25
0
        /// <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());
            }
        }
Beispiel #26
0
        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();
        }
Beispiel #27
0
        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));
        }
Beispiel #28
0
        /// <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);
                    }
            }
        }
Beispiel #29
0
        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();
        }