public void EncodeDefault(MemoryStream OutStream, Bitmap CurrentBitmap, Size blockSize, PixelFormat BitmapFormat)
        {
            BlockScan = blockSize;
            PixelSize = BitmapExtensions.BytesPerPixel(BitmapFormat);
            if (TrailBitmap == null)
            {
                byte[] EncodedBytes = Compressor.Compress(CurrentBitmap);
                OutStream.Write(BitConverter.GetBytes(EncodedBytes.Length), 0, 4);
                OutStream.Write(EncodedBytes, 0, EncodedBytes.Length);
                TrailBitmap = CurrentBitmap;
            }
            else
            {
                BitmapData TrailData   = TrailBitmap.LockBits(new Rectangle(0, 0, TrailBitmap.Width, TrailBitmap.Height), ImageLockMode.ReadOnly, BitmapFormat);
                BitmapData CurrentData = CurrentBitmap.LockBits(new Rectangle(0, 0, CurrentBitmap.Width, CurrentBitmap.Height), ImageLockMode.ReadOnly, BitmapFormat);
                int        Stride      = Math.Abs(TrailData.Stride);
                Task.WaitAll(new[]
                {
                    Task.Run(() => UpperProcess(0, 0, TrailData.Width, TrailData.Height / 2, Stride, TrailData.Scan0, CurrentData.Scan0)),
                    Task.Run(() => LowerProcess(0, TrailData.Height / 2, TrailData.Width, TrailData.Height, Stride, TrailData.Scan0, CurrentData.Scan0)),
                });
                CurrentBitmap.UnlockBits(CurrentData);
                TrailBitmap.UnlockBits(TrailData);

                List <Rectangle> Changes = new List <Rectangle>(UpperChanges.Count + LowerChanges.Count);
                Changes.AddRange(UpperChanges);
                Changes.AddRange(LowerChanges);

                for (int i = 0; i < Changes.Count; ++i)
                {
                    Rectangle Change = Changes[i];
                    OutStream.Write(BitConverter.GetBytes(Change.X), 0, 4);
                    OutStream.Write(BitConverter.GetBytes(Change.Y), 0, 4);
                    OutStream.Write(BitConverter.GetBytes(Change.Width), 0, 4);
                    OutStream.Write(BitConverter.GetBytes(Change.Height), 0, 4);
                    CurrentData = CurrentBitmap.LockBits(new Rectangle(Change.X, Change.Y, Change.Width, Change.Height), ImageLockMode.ReadOnly, BitmapFormat);
                    using (Bitmap ChangedBmp = new Bitmap(Change.Width, Change.Height, CurrentData.Stride, BitmapFormat, CurrentData.Scan0))
                    {
                        byte[] CompressedImage = Compressor.Compress(ChangedBmp);
                        OutStream.Write(BitConverter.GetBytes(CompressedImage.Length), 0, 4);
                        OutStream.Write(CompressedImage, 0, CompressedImage.Length);
                    }
                    CurrentBitmap.UnlockBits(CurrentData);
                }
                TrailBitmap.Dispose();
                TrailBitmap = CurrentBitmap;
                ClearChanges();
            }
        }
예제 #2
0
        private void BenchmarkCompressionSpeed()
        {
            using (Bitmap bmpScreenCapture = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                                        Screen.PrimaryScreen.Bounds.Height))
            {
                using (Graphics g = Graphics.FromImage(bmpScreenCapture))
                {
                    g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                                     Screen.PrimaryScreen.Bounds.Y,
                                     0, 0,
                                     bmpScreenCapture.Size,
                                     CopyPixelOperation.SourceCopy);
                }

                using (var jpgCompressor = new JpgCompression(70))
                {
                    for (int i = 0; i < 5; i++)
                    {
                        var sw = Stopwatch.StartNew();
                        GC.Collect();
                        GC.WaitForPendingFinalizers();

                        using (var outStream = new MemoryStream(10000))
                        {
                            jpgCompressor.Compress(bmpScreenCapture, outStream);
                            var data = outStream.ToArray();
                            Debug.Print("Managed JPG: Time neeeded: " + sw.ElapsedMilliseconds + ", size: " + data.Length);
                        }
                    }
                }

                using (var turboJpg = new NoCompression())
                {
                    turboJpg.Quality = 70;

                    var lockBits =
                        bmpScreenCapture.LockBits(new Rectangle(0, 0, bmpScreenCapture.Width, bmpScreenCapture.Height),
                                                  ImageLockMode.ReadOnly, bmpScreenCapture.PixelFormat);

                    for (int i = 0; i < 5; i++)
                    {
                        GC.Collect();
                        GC.WaitForPendingFinalizers();

                        var sw   = Stopwatch.StartNew();
                        var data = turboJpg.Compress(lockBits.Scan0, lockBits.Stride,
                                                     new System.Drawing.Size(lockBits.Width, lockBits.Height), lockBits.PixelFormat);

                        Debug.Print("LZF: Time neeeded: " + sw.ElapsedMilliseconds + ", size: " + data.Length);
                    }

                    bmpScreenCapture.UnlockBits(lockBits);
                }
            }
        }
예제 #3
0
        public void CompressionTest()
        {
            var quality = Int64.MaxValue;
            var jpg     = new JpgCompression(quality);
            var bitmap  = new Bitmap(200, 200);

            var result = jpg.Compress(bitmap);

            Assert.IsNotNull(result);
            CollectionAssert.AllItemsAreNotNull(result);
        }
예제 #4
0
 public void CompressionTest()
 {
     using (var jpg = new JpgCompression(100))
     {
         using (var bitmap = new Bitmap(200, 200))
             using (var memoryStream = new MemoryStream())
             {
                 jpg.Compress(bitmap, memoryStream);
                 Assert.IsTrue(memoryStream.Length > 0);
             }
     }
 }
예제 #5
0
        public unsafe void CodeImage(IntPtr scan0, Rectangle scanArea, Size imageSize, PixelFormat format,
                                     Stream outStream)
        {
            lock (_imageProcessLock)
            {
                byte *pScan0 = (byte *)scan0.ToInt32();

                if (!outStream.CanWrite)
                {
                    throw new Exception("Must have access to Write in the Stream");
                }

                int stride    = 0;
                int rawLength = 0;
                int pixelSize = 0;

                switch (format)
                {
                case PixelFormat.Format24bppRgb:
                case PixelFormat.Format32bppRgb:
                    pixelSize = 3;
                    break;

                case PixelFormat.Format32bppArgb:
                case PixelFormat.Format32bppPArgb:
                    pixelSize = 4;
                    break;

                default:
                    throw new NotSupportedException(format.ToString());
                }

                stride    = imageSize.Width * pixelSize;
                rawLength = stride * imageSize.Height;

                if (_encodeBuffer == null)
                {
                    this._encodedFormat = format;
                    this._encodedWidth  = imageSize.Width;
                    this._encodedHeight = imageSize.Height;
                    this._encodeBuffer  = new byte[rawLength];

                    fixed(byte *ptr = _encodeBuffer)
                    {
                        byte[] temp = null;
                        using (Bitmap tmpBmp = new Bitmap(imageSize.Width, imageSize.Height, stride, format, scan0))
                        {
                            temp = _jpgCompression.Compress(tmpBmp);
                        }

                        outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
                        outStream.Write(temp, 0, temp.Length);
                        NativeMethods.memcpy(new IntPtr(ptr), scan0, (uint)rawLength);
                    }

                    return;
                }

                if (this._encodedFormat != format)
                {
                    throw new Exception("PixelFormat is not equal to previous Bitmap");
                }
                else if (this._encodedWidth != imageSize.Width || this._encodedHeight != imageSize.Height)
                {
                    throw new Exception("Bitmap width/height are not equal to previous bitmap");
                }

                long oldPos = outStream.Position;
                outStream.Write(new byte[4], 0, 4);
                long totalDataLength = 0;

                List <Rectangle> blocks = new List <Rectangle>();

                Size s        = new Size(scanArea.Width, CheckBlock.Height);
                Size lastSize = new Size(scanArea.Width % CheckBlock.Width, scanArea.Height % CheckBlock.Height);

                int lasty = scanArea.Height - lastSize.Height;
                int lastx = scanArea.Width - lastSize.Width;

                Rectangle        cBlock       = new Rectangle();
                List <Rectangle> finalUpdates = new List <Rectangle>();

                s = new Size(scanArea.Width, s.Height);

                fixed(byte *encBuffer = _encodeBuffer)
                {
                    var index = 0;

                    for (int y = scanArea.Y; y != scanArea.Height; y += s.Height)
                    {
                        if (y == lasty)
                        {
                            s = new Size(scanArea.Width, lastSize.Height);
                        }

                        cBlock = new Rectangle(scanArea.X, y, scanArea.Width, s.Height);

                        int offset = (y * stride) + (scanArea.X * pixelSize);

                        if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)stride) != 0)
                        {
                            index = blocks.Count - 1;

                            if (blocks.Count != 0 && (blocks[index].Y + blocks[index].Height) == cBlock.Y)
                            {
                                cBlock = new Rectangle(blocks[index].X, blocks[index].Y, blocks[index].Width,
                                                       blocks[index].Height + cBlock.Height);
                                blocks[index] = cBlock;
                            }
                            else
                            {
                                blocks.Add(cBlock);
                            }
                        }
                    }

                    for (int i = 0; i < blocks.Count; i++)
                    {
                        s = new Size(CheckBlock.Width, blocks[i].Height);

                        for (int x = scanArea.X; x != scanArea.Width; x += s.Width)
                        {
                            if (x == lastx)
                            {
                                s = new Size(lastSize.Width, blocks[i].Height);
                            }

                            cBlock = new Rectangle(x, blocks[i].Y, s.Width, blocks[i].Height);
                            bool foundChanges = false;
                            uint blockStride  = (uint)(pixelSize * cBlock.Width);

                            for (int j = 0; j < cBlock.Height; j++)
                            {
                                int blockOffset = (stride * (cBlock.Y + j)) + (pixelSize * cBlock.X);

                                if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, blockStride) != 0)
                                {
                                    foundChanges = true;
                                }

                                NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, blockStride);
                                //copy-changes
                            }

                            if (foundChanges)
                            {
                                index = finalUpdates.Count - 1;

                                if (finalUpdates.Count > 0 &&
                                    (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
                                {
                                    Rectangle rect     = finalUpdates[index];
                                    int       newWidth = cBlock.Width + rect.Width;
                                    cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
                                    finalUpdates[index] = cBlock;
                                }
                                else
                                {
                                    finalUpdates.Add(cBlock);
                                }
                            }
                        }
                    }
                }

                for (int i = 0; i < finalUpdates.Count; i++)
                {
                    Rectangle rect        = finalUpdates[i];
                    int       blockStride = pixelSize * rect.Width;

                    Bitmap     tmpBmp  = null;
                    BitmapData tmpData = null;
                    long       length;

                    try
                    {
                        tmpBmp  = new Bitmap(rect.Width, rect.Height, format);
                        tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height),
                                                  ImageLockMode.ReadWrite, tmpBmp.PixelFormat);

                        for (int j = 0, offset = 0; j < rect.Height; j++)
                        {
                            int blockOffset = (stride * (rect.Y + j)) + (pixelSize * rect.X);
                            NativeMethods.memcpy((byte *)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride);
                            //copy-changes
                            offset += blockStride;
                        }

                        outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
                        outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
                        outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
                        outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
                        outStream.Write(new byte[4], 0, 4);

                        length = outStream.Length;
                        long old = outStream.Position;

                        _jpgCompression.Compress(tmpBmp, ref outStream);

                        length = outStream.Position - length;

                        outStream.Position = old - 4;
                        outStream.Write(BitConverter.GetBytes(length), 0, 4);
                        outStream.Position += length;
                    }
                    finally
                    {
                        tmpBmp.UnlockBits(tmpData);
                        tmpBmp.Dispose();
                    }

                    totalDataLength += length + (4 * 5);
                }

                outStream.Position = oldPos;
                outStream.Write(BitConverter.GetBytes(totalDataLength), 0, 4);
            }
        }
예제 #6
0
        public unsafe void CodeImage(IntPtr Scan0, Rectangle[] Changes, Size ImageSize, PixelFormat Format, Stream outStream)
        {
            byte *pScan0 = (byte *)Scan0.ToInt32();

            if (!outStream.CanWrite)
            {
                throw new Exception("Must have access to Write in the Stream");
            }

            int Stride    = 0;
            int RawLength = 0;
            int PixelSize = 0;

            switch (Format)
            {
            case PixelFormat.Format24bppRgb:
                PixelSize = 3;
                break;

            case PixelFormat.Format32bppArgb:
            case PixelFormat.Format32bppPArgb:
                PixelSize = 4;
                break;

            default:
                throw new NotSupportedException(Format.ToString());
            }

            Stride    = ImageSize.Width * PixelSize;
            RawLength = Stride * ImageSize.Height;

            if (EncodeBuffer == null)
            {
                this.EncodedFormat = Format;
                this.EncodedWidth  = ImageSize.Width;
                this.EncodedHeight = ImageSize.Height;
                this.EncodeBuffer  = new byte[RawLength];
                fixed(byte *ptr = EncodeBuffer)
                {
                    byte[] temp = null;
                    using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
                    {
                        temp = jpgCompression.Compress(TmpBmp);
                    }

                    outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
                    outStream.Write(temp, 0, temp.Length);
                    NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
                }

                return;
            }

            long oldPos = outStream.Position;

            outStream.Write(new byte[4], 0, 4);
            int TotalDataLength = 0;

            for (int i = 0; i < Changes.Length; i++)
            {
                Rectangle rect        = Changes[i];
                int       blockStride = PixelSize * rect.Width;

                Bitmap     TmpBmp  = new Bitmap(rect.Width, rect.Height, Format);
                BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat);
                for (int j = 0, offset = 0; j < rect.Height; j++)
                {
                    int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
                    NativeMethods.memcpy((byte *)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
                    offset += blockStride;
                }
                TmpBmp.UnlockBits(TmpData);

                outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
                outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
                outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
                outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
                outStream.Write(new byte[4], 0, 4);

                long length = outStream.Position;
                long OldPos = outStream.Position;
                jpgCompression.Compress(TmpBmp, ref outStream);
                length = outStream.Position - length;

                outStream.Position = OldPos - 4;
                outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
                outStream.Position += length;
                TmpBmp.Dispose();
                TotalDataLength += (int)length + (4 * 5);
            }
            outStream.Position = oldPos;
            outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
        }
예제 #7
0
        public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
        {
            lock (ImageProcessLock)
            {
                byte *pScan0;

                if (IntPtr.Size == 8)
                {
                    // 64 bit process
                    pScan0 = (byte *)Scan0.ToInt64();
                }
                else
                {
                    // 32 bit process
                    pScan0 = (byte *)Scan0.ToInt32();
                }

                if (!outStream.CanWrite)
                {
                    throw new Exception("Must have access to Write in the Stream");
                }

                int Stride    = 0;
                int RawLength = 0;
                int PixelSize = 0;

                switch (Format)
                {
                case PixelFormat.Format24bppRgb:
                case PixelFormat.Format32bppRgb:
                    PixelSize = 3;
                    break;

                case PixelFormat.Format32bppArgb:
                case PixelFormat.Format32bppPArgb:
                    PixelSize = 4;
                    break;

                default:
                    throw new NotSupportedException(Format.ToString());
                }

                Stride    = ImageSize.Width * PixelSize;
                RawLength = Stride * ImageSize.Height;

                if (EncodeBuffer == null)
                {
                    this.EncodedFormat = Format;
                    this.EncodedWidth  = ImageSize.Width;
                    this.EncodedHeight = ImageSize.Height;
                    this.EncodeBuffer  = new byte[RawLength];
                    fixed(byte *ptr = EncodeBuffer)
                    {
                        byte[] temp = null;
                        using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0))
                        {
                            temp = base.jpgCompression.Compress(TmpBmp);
                        }

                        outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
                        outStream.Write(temp, 0, temp.Length);
                        NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength);
                    }

                    return;
                }

                if (this.EncodedFormat != Format)
                {
                    throw new Exception("PixelFormat is not equal to previous Bitmap");
                }

                if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height)
                {
                    throw new Exception("Bitmap width/height are not equal to previous bitmap");
                }

                long oldPos = outStream.Position;
                outStream.Write(new byte[4], 0, 4);
                long TotalDataLength = 0;

                List <Rectangle> Blocks = new List <Rectangle>();

                Size s        = new Size(ScanArea.Width, CheckBlock.Height);
                Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height);

                int lasty = ScanArea.Height - lastSize.Height;
                int lastx = ScanArea.Width - lastSize.Width;

                Rectangle        cBlock       = new Rectangle();
                List <Rectangle> finalUpdates = new List <Rectangle>();

                s = new Size(ScanArea.Width, s.Height);
                fixed(byte *encBuffer = EncodeBuffer)
                {
                    var index = 0;

                    //for (int y = ScanArea.Y; y != ScanArea.Height; )
                    for (int y = ScanArea.Y; y != ScanArea.Height; y += s.Height)
                    {
                        if (y == lasty)
                        {
                            s = new Size(ScanArea.Width, lastSize.Height);
                        }

                        cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height);

                        //if (onCodeDebugScan != null)
                        //    onCodeDebugScan(cBlock);

                        int offset = (y * Stride) + (ScanArea.X * PixelSize);

                        if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
                        {
                            index = Blocks.Count - 1;

                            if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y)
                            {
                                cBlock        = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height);
                                Blocks[index] = cBlock;
                            }
                            else
                            {
                                Blocks.Add(cBlock);
                            }
                        }
                    }

                    for (int i = 0; i < Blocks.Count; i++)
                    {
                        s = new Size(CheckBlock.Width, Blocks[i].Height);

                        for (int x = ScanArea.X; x != ScanArea.Width; x += s.Width)
                        {
                            if (x == lastx)
                            {
                                s = new Size(lastSize.Width, Blocks[i].Height);
                            }

                            cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height);
                            bool foundChanges = false;
                            uint blockStride  = (uint)(PixelSize * cBlock.Width);

                            for (int j = 0; j < cBlock.Height; j++)
                            {
                                int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X);

                                if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, blockStride) != 0)
                                {
                                    foundChanges = true;
                                }

                                NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, blockStride);
                                //copy-changes
                            }

                            if (foundChanges)
                            {
                                index = finalUpdates.Count - 1;

                                if (finalUpdates.Count > 0 &&
                                    (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
                                {
                                    Rectangle rect     = finalUpdates[index];
                                    int       newWidth = cBlock.Width + rect.Width;
                                    cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
                                    finalUpdates[index] = cBlock;
                                }
                                else
                                {
                                    finalUpdates.Add(cBlock);
                                }
                            }
                        }
                    }
                }

                /*int maxHeight = 0;
                 * int maxWidth = 0;
                 *
                 * for (int i = 0; i < finalUpdates.Count; i++)
                 * {
                 *  if (finalUpdates[i].Height > maxHeight)
                 *      maxHeight = finalUpdates[i].Height;
                 *  maxWidth += finalUpdates[i].Width;
                 * }
                 *
                 * Bitmap bmp = new Bitmap(maxWidth+1, maxHeight+1);
                 * int XOffset = 0;*/

                for (int i = 0; i < finalUpdates.Count; i++)
                {
                    Rectangle rect        = finalUpdates[i];
                    int       blockStride = PixelSize * rect.Width;

                    Bitmap     tmpBmp  = null;
                    BitmapData tmpData = null;
                    long       length;

                    try
                    {
                        tmpBmp  = new Bitmap(rect.Width, rect.Height, Format);
                        tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height),
                                                  ImageLockMode.ReadWrite, tmpBmp.PixelFormat);

                        for (int j = 0, offset = 0; j < rect.Height; j++)
                        {
                            int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X);
                            NativeMethods.memcpy((byte *)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride);
                            //copy-changes
                            offset += blockStride;
                        }

                        outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
                        outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
                        outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
                        outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4);
                        outStream.Write(new byte[4], 0, 4);

                        length = outStream.Length;
                        long old = outStream.Position;

                        _jpgCompression.Compress(tmpBmp, ref outStream);

                        length = outStream.Position - length;

                        outStream.Position = old - 4;
                        outStream.Write(BitConverter.GetBytes(length), 0, 4);
                        outStream.Position += length;
                    }
                    finally
                    {
                        tmpBmp.UnlockBits(tmpData);
                        tmpBmp.Dispose();
                    }

                    TotalDataLength += length + (4 * 5);
                }

                outStream.Position = oldPos;
                outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
            }
        }
예제 #8
0
        private void ProcessResponse(byte parameter, int size, byte[] bytes)
        {
            switch ((FromAdministrationPackage)parameter)
            {
            case FromAdministrationPackage.InitializeNewSession:
                var id         = BitConverter.ToUInt16(bytes, 0);
                var connection = new AdministrationConnection(id, this, _clientInfo);
                connection.SendFailed += (sender, args) => Dispose();

                AdministrationConnections.Add(connection);
                lock (SendLock)
                {
                    BinaryWriter.Write((byte)FromClientPackage.ResponseLoginOpen);
                    BinaryWriter.Write(2);
                    BinaryWriter.Write(BitConverter.GetBytes(id));
                }
                break;

            case FromAdministrationPackage.SendStaticCommand:
                var potentialCommand =
                    new Serializer(typeof(PotentialCommand)).Deserialize <PotentialCommand>(bytes, 0);

                StaticCommandSelector.Current.ExecuteCommand(potentialCommand);
                break;

            case FromAdministrationPackage.SendStaticCommandCompressed:
                potentialCommand =
                    new Serializer(typeof(PotentialCommand)).Deserialize <PotentialCommand>(LZF.Decompress(bytes, 0), 0);

                StaticCommandSelector.Current.ExecuteCommand(potentialCommand);
                break;

            case FromAdministrationPackage.LoadPlugin:
                var guid    = new Guid(bytes.Skip(2).Take(16).ToArray());
                var version = new Serializer(typeof(PluginVersion)).Deserialize <PluginVersion>(bytes,
                                                                                                18);
                var versionData = Encoding.ASCII.GetBytes(version.ToString());
                if (LoadPlugin(guid, version))
                {
                    lock (SendLock)
                    {
                        BinaryWriter.Write((byte)FromClientPackage.PluginLoaded);
                        BinaryWriter.Write(16 + versionData.Length);
                        BinaryWriter.Write(guid.ToByteArray());
                        BinaryWriter.Write(versionData);
                    }
                }
                else
                {
                    lock (SendLock)
                    {
                        BinaryWriter.Write((byte)FromClientPackage.PluginLoadFailed);
                        BinaryWriter.Write(2 + 16 + versionData.Length);
                        BinaryWriter.Write(bytes, 0, 2);     //administration id
                        BinaryWriter.Write(guid.ToByteArray());
                        BinaryWriter.Write(versionData);
                    }
                }
                break;

            case FromAdministrationPackage.CloseSession:
                var closingSessionId = BitConverter.ToUInt16(bytes, 0);
                var session          = AdministrationConnections.FirstOrDefault(x => x.Id == closingSessionId);
                if (session != null)
                {
                    AdministrationConnections.Remove(session);
                    session.Dispose();
                }
                break;

            case FromAdministrationPackage.GetActiveWindow:
                try
                {
                    string windowTitle = "";

                    var lastInPut = new LASTINPUTINFO();
                    lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut);

                    //15 min
                    if (NativeMethods.GetLastInputInfo(ref lastInPut) &&
                        (uint)Environment.TickCount - lastInPut.dwTime > 900000)
                    {
                        windowTitle += "[Idle] ";
                    }

                    windowTitle += ActiveWindowHook.GetActiveWindowTitle() ?? "";
                    var windowTitleData = Encoding.UTF8.GetBytes(windowTitle);
                    lock (SendLock)
                    {
                        BinaryWriter.Write((byte)FromClientPackage.ResponseActiveWindow);
                        BinaryWriter.Write(windowTitleData.Length + 2);
                        BinaryWriter.Write(bytes);
                        BinaryWriter.Write(windowTitleData);
                    }
                }
                catch (Exception ex)
                {
                    ErrorReporter.Current.ReportError(ex,
                                                      "case FromAdministrationPackage.GetActiveWindow");
                }
                break;

            case FromAdministrationPackage.GetScreen:
                try
                {
                    using (var compressor = new JpgCompression(75))
                    {
                        byte[] screenshotData;
                        using (var memoryStream = new MemoryStream())
                            using (var screenshot = ScreenHelper.TakeScreenshot())
                            {
                                compressor.Compress(screenshot, memoryStream);
                                screenshotData = memoryStream.ToArray();
                            }

                        lock (SendLock)
                        {
                            BinaryWriter.Write((byte)FromClientPackage.ResponseScreenshot);
                            BinaryWriter.Write(screenshotData.Length + 2);
                            BinaryWriter.Write(bytes);
                            BinaryWriter.Write(screenshotData);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ErrorReporter.Current.ReportError(ex, "case FromAdministrationPackage.GetScreen");
                }
                break;

            case FromAdministrationPackage.AcceptPush:
                FileTransferAccepted?.Invoke(this, new FileTransferEventArgs(new Guid(bytes)));
                break;

            case FromAdministrationPackage.TransferCompleted:
                FileTransferCompleted?.Invoke(this, new FileTransferEventArgs(new Guid(bytes)));
                break;

            case FromAdministrationPackage.IsAlive:
                lock (SendLock)
                {
                    BinaryWriter.Write((byte)FromClientPackage.StillAlive);
                    BinaryWriter.Write(0);
                }
                break;

            case FromAdministrationPackage.SendStaticCommandPlugin:
                var pluginDirectory = new DirectoryInfo(Consts.StaticCommandPluginsDirectory);
                if (!pluginDirectory.Exists)
                {
                    pluginDirectory.Create();
                }

                var filename = FileExtensions.GetUniqueFileName(pluginDirectory.FullName);
                using (var fileStream = new FileStream(filename, FileMode.CreateNew, FileAccess.Write))
                    fileStream.Write(bytes, 4, bytes.Length - 4);

                StaticCommandPluginReceived?.Invoke(this, new StaticCommandPluginReceivedEventArgs(filename,
                                                                                                   BitConverter.ToInt32(bytes, 0)));
                break;

            case FromAdministrationPackage.RequestLibraryInformation:
                var libraries     = (PortableLibrary)BitConverter.ToInt32(bytes, 2);
                var libraryHashes = (size - 6) / 16;
                var hashes        = new List <byte[]>(libraryHashes);
                for (int i = 0; i < libraryHashes; i++)
                {
                    var hash = new byte[16];
                    Buffer.BlockCopy(bytes, 6 + i * 16, hash, 0, 16);
                    hashes.Add(hash);
                }
                var result = LibraryLoader.Current.CheckLibraries(libraries, hashes);
                lock (SendLock)
                {
                    BinaryWriter.Write((byte)FromClientPackage.ResponseLibraryInformation);
                    BinaryWriter.Write(6);
                    BinaryWriter.Write(bytes, 0, 2);     //administration id
                    BinaryWriter.Write(BitConverter.GetBytes((int)result));
                }
                break;

            case FromAdministrationPackage.StopActiveCommand:
                StaticCommandSelector.Current.StopActiveCommand(BitConverter.ToInt32(bytes, 0));
                break;
            }
        }